@react_js

Страница 127 из 5115
Антон
25.05.2016
09:27:56
Ну альтернативой его вряд ли назовешь

Но упаковывать либы удобненько

Alexander
25.05.2016
09:39:56
Привет чатик, подскажите, что сейчас самый свежак для react hot reload? Использовал react-transform-hmr, зашел на страницу проекта, а он вдруг deprecated. Там же говорят react-hot-loader использовать. Есть мысли на этот счет?

cloudo
25.05.2016
09:41:16
пока смотри сюда... https://github.com/gaearon/react-hot-boilerplate

Google
cloudo
25.05.2016
09:41:51
когда будет новый rhl, обновится и бойлерплейт

там же уже есть бранч с альфой rhl3

Alexander
25.05.2016
09:42:39
ага, про него и думал. Спасибо

Alexander
25.05.2016
10:09:54
друзья, мне интересно ваше мнение об эксперементальном подходе к работе с редуксом, который мы испольуем в текущем довольно крупном проекте. Он кажется нам весьма классным и сильно повышающим качество кода. Суть в том, что ты коннектишь компонент к срезу редуксовского стейта и можешь работать с этим куском стейта примерно так же как если бы это был обычный реактовский стейт. через setState, replaceState. Получается не нужно писать акшены/константы/редюсеры на каждый чих. И за действие которое комонент хочет совершить он отвечает сам, а не размазывает эту ответственность между собой, экшеном и редьюсером.

подробнее тут: https://medium.com/@nosovsh/redux-without-reducers-actions-and-constants-wat-72fcd838c641#.uqmlw2bnl

простенькая либа, которую для этого написали, тут: https://github.com/nosovsh/reduceless

Vladimir
25.05.2016
10:12:11
? я читал статью и мне нравится такой подход, но не пробовал ещё

Vladimir
25.05.2016
10:15:20
то есть вы делаете setState, но он не устанавливает стейт, а делает что-то еще?

Алексей
25.05.2016
10:22:07
А если у меня два разных компонента, которые могут работать с одним куском state, и допустим есть метод notSimpleSetState, которые изменяет state,но перед этим еще что-то делая ( тот же аякс запрос ). Как мне впихнуть этот метод в оба компонента? Дублировать? Наследовать один от другого? Либо выносить метод отдельно куда-то ( что по сути тот же action )

Alexander
25.05.2016
10:24:04
то есть вы делаете setState, но он не устанавливает стейт, а делает что-то еще?
обертка передает state и setState через props в компонент. В обертке оказываешь какая часть редкусовского стейта тебе нужна. например 'blog_page.left_sidebar.form'. Внутри компонента можно читать то что лежит в этой части редуксовского стейта из "state" пропса(наприме, "state.first_name") и писать в него обратно (например setState({"first_name": "ololo"})). И этот setState вызовет свой экшен и запишет это значение в редуксовский стейт по тому пути, по которому ты указал. То есть технически локальный стейт компонента вообще не используется, идет работа сразу с редуксовским(из-за этого нет проблем с рассинхронизацией стейтов, он всегда один глобальный), а для разработчика все выглядит очень похожим на работу с локальным реактовским стейтом

это же курсоры по сути? baobab, clojure om v1, ValueLinks — вот это всё?
baobab и иже с ним это отдельные сложные штуки добавляющие свои конецпции и все такое. Здесь же просто удобная работа с редуксом ValueLink чем то похоже, но во-первых у нас нет этой скрытой магии two-way data binding(из-за который они deprecated). Ты сам, явно вызываешь setState когда нужно, а во вторых ValueLink работает с локальным стейтом, а мы используем глобальный редуксовский стейт

то есть вы делаете setState, но он не устанавливает стейт, а делает что-то еще?
мы "устанавливаем"(изменяем) кусок редуксовского стейта, который нужен компоненту. В кишках эта обертка вызывает своей экшен передавая ему путь до этого стейта и твое новое значение и ловит этот экшен в своем редюсере, где и устанавливает и записывает это значение. То есть каждый компонент коннектится к своему куску редуксовсего стейта и дальше делает со своим куском что хочет. И естественно несколько компонентов могут присобачиваться к отдному и тому же куску. И вот тут то получается весь профит того, что весь стейт хранится в одном месте, а не размазан по компонентам

Google
Alexander
25.05.2016
10:40:41
А если у меня два разных компонента, которые могут работать с одним куском state, и допустим есть метод notSimpleSetState, которые изменяет state,но перед этим еще что-то делая ( тот же аякс запрос ). Как мне впихнуть этот метод в оба компонента? Дублировать? Наследовать один от другого? Либо выносить метод отдельно куда-то ( что по сути тот же action )
Необходимость работать разным комопнентам с одним и тем же куском это одна из причин почему мы это все используем, а не просто локальные стейты у каждого из этих компонентов. логику notSimpleSetState тебе все равно придется где-то писать. Это твоя кастомная бизнес логика, которую никакая либа не напишет. Дальше вопрос, где эту логику описывать? В голом редуксе эта логика получается размазана. Часть ее приходится делать в компоненте (например, если нужно опираться на другие части стейта, собственно ловить события пользователя и др), часть в акшене(если что то асинхронное), часть в редюсере(собственно установка значения). Мы со временем начали путаться в этом насильственном разделении. И в новом подходе главное, что компонент отвечает за всю эту логику, с него весь спрос. А где он ее описывает уже его дело. Это может быть отдельная хелпер функция, может быть просто метод объекта(если логика простая), может быть инлайн () =>setState(...), может быть какой то отдельные класс для бизнес апи.

А если у меня два разных компонента, которые могут работать с одним куском state, и допустим есть метод notSimpleSetState, которые изменяет state,но перед этим еще что-то делая ( тот же аякс запрос ). Как мне впихнуть этот метод в оба компонента? Дублировать? Наследовать один от другого? Либо выносить метод отдельно куда-то ( что по сути тот же action )
И еще важно, что использование этого подхода (этой либы) не ограничивает в использовании редукса "обычным" способом. В первую очередь она хороша для простых set/get операций (установка фильтра, выбор активного таба и др) для которых не хочется писать кучу банальны экшенов, констант, редюсеров. А для асинхронных вещей можно продолжать использовать любимые вещи(redux-thunk, saga, graphql и др)

? я читал статью и мне нравится такой подход, но не пробовал ещё
ждем отзывов! есть куча идей как развивать подход дальше

Евгений
25.05.2016
10:53:05
И если бы мой текущий проект был на react, то я именно их бы использовал.

cloudo
25.05.2016
11:04:40
выглядит годно, надо будет попробовать

Roman
25.05.2016
11:34:54
присоединяюсь, идея отличная ?

Евгений
25.05.2016
11:36:54
@trashgenerator https://github.com/Yomguithereal/baobab

Alexander
25.05.2016
11:46:44
удваиваю, это курсоры
Курсоры очень похожая идея (и это хорошо, меньше концепций больше места в мозгу!), спасибо за наводку. Буду изучать глубже. Особенно кто как их использует с редуксом. баобаб это скорее альтернатива редуксу. В целом мне нравится редукс, не знаю баобаб "лучше" или "хуже", но слезать с редукса по середине большого проекта анриал, а вот изменить подход к его использованию можно

@maullerz @cloudo58 буду рад услышать потом ваши мысли

Vadim
25.05.2016
11:51:36
эммм, альтернатива? baobao больше похож на менеджер данных с иммутабельностью, по типу Immutable.js, чем на альтернативу редаксу.

Alexander
25.05.2016
11:58:31
Vadim ну значит это альтернатива обычным джаваскрипт объектам, которые храняться в стейте. Опять же таки не уверен, что нужно от них отказываться в пользу баобаба/иммутейблжс только из-за курсоров. Много других плюсов и минусов, которые надо рассматривать

lolkrp
25.05.2016
12:11:27
Подскажите плз я собираю вебпаком небольшое учебное приложение, и оно собирается 4937ms

var webpack = require('webpack'); var merge = require('webpack-merge'); var NpmInstallPlugin = require('npm-install-webpack-plugin'); var ExtractTextPlugin = require('extract-text-webpack-plugin'); var HtmlWebpackPlugin = require('html-webpack-plugin'); var HTMLWebpackPluginConfig = new HtmlWebpackPlugin({ template: __dirname + '/app/index.html', filename: 'index.html', inject : 'body' }); var TARGET = process.env.npm_lifecycle_event; var common = { cache : true, debug : true, context: __dirname + '/app', entry : { main: './index.js' }, output: { path: ${__dirname}/dist, filename: '[name].js', chunkFilename: '[id].js', sourceMapFilename: '[file].map' }, resolve: { extensions: ['', '.js', '.jsx', '.less'] }, module: { loaders: [{ test: /\.jsx?$/, include: ${__dirname}/app, loader: 'babel-loader' }, { test: /\.css$/, loader: ExtractTextPlugin.extract('style-loader', 'css-loader') }, { test: /\.less$/, loader: ExtractTextPlugin.extract('style-loader', 'css-loader?sourceMap!less-loader?sourceMap') }, { test: /\.woff$/, loader: 'url-loader?limit=10000&mimetype=application/font-woff&name=[path][name].[ext]' }, { test: /\.woff2$/, loader: 'url-loader?limit=10000&mimetype=application/font-woff2&name=[path][name].[ext]' }, { test: /\.(eot|ttf|svg|gif|png)$/, loader: 'file-loader' }] }, plugins: [ new webpack.ProvidePlugin({ $: 'jquery', jQuery: 'jquery' }), new ExtractTextPlugin('[name].css') ] }; if (TARGET === 'dev' || !TARGET) { module.exports = merge(common, { devtool: 'eval-source-map', devServer: { port: 8090, historyApiFallback: true, hot: false, contentBase: ${__dirname}/dist }, watch: true, plugins: [ new NpmInstallPlugin({ save: true // --save }) ] }); } if (TARGET === 'build') { module.exports = merge(common, { devtool: 'source-map', output: { path: ${__dirname}/dist }, plugins: [ HTMLWebpackPluginConfig ] }); }

фот конфиг

Евгений
25.05.2016
12:15:49
Спасибо, но лучше куда-нибудь на jsfiddle или codepen.io выложить

Vladimir
25.05.2016
12:16:00
5 сек это ж вроде нормально, не?)

lolkrp
25.05.2016
12:16:32
http://codepen.io/pen/?editors=0010

Google
lolkrp
25.05.2016
12:16:49
так как-то хз...

Vladimir
25.05.2016
12:16:59
можно добавить include к бабель лоадеру чтоб он только нужные файлы транспилил, и пропускал всякие нод модули

Alexander
25.05.2016
12:17:08
5 сек это ж вроде нормально, не?)
у нас уже минуту наверно точно компилится)

Vladimir
25.05.2016
12:17:25
а вот минута это перебор

если для дев режима)

Alexander
25.05.2016
12:18:01
если он уже запущен, то почти моментально пересобирает изменения. это если заново запускать

lolkrp
25.05.2016
12:18:06
та и 5 сек для dev - много... я подозреваю шо это из-за инклудов

я мож не прав но в каждой компоненте пишу import React from 'react';

Alexander
25.05.2016
12:19:01
все правильно

Vladimir
25.05.2016
12:19:27
укажи в include путь к своим исходным файлам: https://github.com/kriasoft/react-starter-kit/blob/master/tools/webpack.config.js#L51-L54

типа такого, возможно чуть чуть сократит время сборки)

lolkrp
25.05.2016
12:23:03
к либам тоже?

Vladimir
25.05.2016
12:23:39
нет, либы же не надо транспилить ES7/ES6 -> ES5

Vladimir
25.05.2016
12:24:04
а в режиме вотча за сколько происходит перекомпиляция?

а NpmInstallPlugin не тормозит ли?

lolkrp
25.05.2016
12:25:27
ну стока же

5сек

тю ток шо понял шо у меня инклуд для бабеля стоит..

hlomzik
25.05.2016
12:35:13
это неправильная ссылка)

http://codepen.io/pen/?editors=0010

Google
anoru
25.05.2016
12:36:54
@trashgenerator Выглядит интересно, но внутри компонента всю логику писать бы не стал, чтобы каши не было. И возникает как раз вопрос - а в какие файлы вы потом переносите весь этот код с setState. Это лежит рядом в утилсе с компонентом? А если надо нескольким компонентам?

lolkrp
25.05.2016
12:38:38
https://jsfiddle.net/#&togetherjs=wMBrqMwUrN

Alexander
25.05.2016
12:42:44
@trashgenerator Выглядит интересно, но внутри компонента всю логику писать бы не стал, чтобы каши не было. И возникает как раз вопрос - а в какие файлы вы потом переносите весь этот код с setState. Это лежит рядом в утилсе с компонентом? А если надо нескольким компонентам?
В основном мы используем ее там, где нет смысла выносить эту логику. если надо выбрать табу, то лучше написать onClick={() => props.setState('selectedTab': i)} в нескольких компонентах, чем выносить это в отдельный модуль. Или скажем установить значение фильтра при клике на кнопку onClick={() => props.replaceState(newFilter)}. Если действительно что то сложное появляется, то выносим в модуль отдельно от компонентов

anoru
25.05.2016
12:43:23
Кстати, также стоит учитывать, что redux ducks намного упрощает разработку. А когда редюсер и экшены находятся в одном файле, то и нет смысла юзать константы. Очень редко 1 экшен в нескольких редюсерах слушается.А если такое и бывает, то можно руками 2 раза повторить строчку. Это значительно уменьшает количество кода, но все равно не идеально) Так что вариант выше нравится больше, конечно Ж)

@trashgenerator То есть в сложных местах как раньше юзаете? Или такой же подход, но просто выносится в файл. Вопрос о том мигрировали ли полностью с обычного redux подхода на этот или нет :)

Alexander
25.05.2016
12:46:10
Кстати, также стоит учитывать, что redux ducks намного упрощает разработку. А когда редюсер и экшены находятся в одном файле, то и нет смысла юзать константы. Очень редко 1 экшен в нескольких редюсерах слушается.А если такое и бывает, то можно руками 2 раза повторить строчку. Это значительно уменьшает количество кода, но все равно не идеально) Так что вариант выше нравится больше, конечно Ж)
Если я правильно понял ducks, то они не делают так, что бы один и тот же модуль можно было бы привязывать к разным частям стейта. То есть constants у них захардкожены. Не получится один и тот же ducks скажем для управления табами использовать для несвязаных табов расположеных в разных местах

Grigory
25.05.2016
12:47:21
вот это кстати не очень хорошо onClick={() => props.setState('selectedTab': i)}

anoru
25.05.2016
12:48:26
хм, не понял. Там же нет никаких ограничений, просто кода меньше писать. Можно сделать duck модуль tabs. Там хранить состояние всех табов разных частей приложения,хотя это неправильно, думаю. Состояние

ой,случайно ентер нажал. В веб интерфейсе телеграма нет редактирования )

Admin
ERROR: S client not available

anoru
25.05.2016
12:49:31
дак вот. в модуле tabs можно хранить лишь экшены, а само значение в других модулях. Ну и там слушать экшен CHANGE_TAB

вообщем в redux ducks все тоже самое. Но писанины все равно много )

Grigory
25.05.2016
12:50:51
Ага а еще при каждом рендере создает новую функцию

anoru
25.05.2016
12:51:40
Ну, все эти споры всегда кончаются тем,что на скорость это особо не влияет

Еще год назад решили)

Но на самом деле для табов, чекбоксов, выпадаек и прочей мелкой штуки идеально подходит.

Но с другой стороны это все можно и в стейте хранить

Grigory
25.05.2016
12:56:01
Я кстати для борьбы с бойлер плейтом делал такую штуку но что-то никому похоже не зашло

https://github.com/grigory-leonenko/redux-easy-actions

Google
anoru
25.05.2016
12:56:37
о, я видел это )

даже лайк стоит )

Alexander
25.05.2016
12:59:41
Но на самом деле для табов, чекбоксов, выпадаек и прочей мелкой штуки идеально подходит.
вот, да! именно обилией экшенов, редюсеров и констрант для этой неченсти и вгоняло нас в тоску. Не всегда получается это в локальном стейте хранть, потому что зачастую другим компонентам тоже нужен доступ к этоим значениям

Grigory
25.05.2016
13:00:20
даже лайк стоит )
благодарствую?

anoru
25.05.2016
13:00:26
Есть еще вот такая штука

https://github.com/calvinfroedge/redux-modifiers

но я не юзал

Alexander
25.05.2016
13:00:36
вот это кстати не очень хорошо onClick={() => props.setState('selectedTab': i)}
для простоты так написал. В реальной жизни смотрим по обстоятельствам. если стоит того, то конечно выносим в отдельный метод onClick={this.setActiveTab}

Grigory
25.05.2016
13:02:35
Кстати вот здесь мне понравилась их идея с handleAction https://github.com/acdlite/redux-actions

Alexander
25.05.2016
13:05:07
а для того что бы использовать один и тот же код для констант, редюсеров, экшенов в разных местах, мы делаем их параметризируемыми. типа: ` export default function getCollapserModule(prefix) { const constants = { TOGGLE: prefix + '/TOGGLE',

ауч

` export default function getCollapserModule(prefix) { const constants = { TOGGLE: prefix + '/TOGGLE', } actions: { toggle: (id) => ({type: constants.TOGGLE, id}), } reducer: { бла лба } `

блин, не очень понятно получилось) короче добавляем префикс к константам для разных мест. получает одна и та же функция редюсера реагирует на похожие(но разные по префиксу) константы и изменяет разные места в стейте

Daniil
25.05.2016
13:09:32
на 100 разных экшнев будет юзаться 2 экшена? если это локал стэйт компонента то нафига вобще этот стейт в редакс тащить

Alexander
25.05.2016
13:11:22
на 100 разных экшнев будет юзаться 2 экшена? если это локал стэйт компонента то нафига вобще этот стейт в редакс тащить
на сто разных мест в редуксовском стейте (допустим у тебя есть сто разных виджетов с табами у которых не связанные, но одинаковые по форме стейты) будет использоваться всего два экшена и один редюсер распиханый в сто разных мест

стейт в редакс тащим не по своей воле. если к одному и тому же стейту нужен доступ из двух разных мест, то это оптимальный выбор

допустим есть табы со стейтом где хранится айди открытой табы, а есть где то фильтр этих табов совсем в другом месте и при активации фильтра надо сбрасывать индекса открытого таба на 0

cloudo
25.05.2016
13:12:53
если нужно синхронизировать с сервером, например... я для модальных окон юзаю локальный стейт, а для кейса выше - вполне норм

Alexander
25.05.2016
13:13:37
если нужно синхронизировать с сервером, например... я для модальных окон юзаю локальный стейт, а для кейса выше - вполне норм
да, я тоже сначала юзаю локальный стейт. чуть он где понадобился еще - выношу в редукс. Поэтому хочется иметь удобный инструмент, когда компоненту пофигу где стейт

Daniil
25.05.2016
13:14:05
если экшны дергают разные места стейта и имеют разные функции у тебя будет все равно использоваться 2 экшна

и что ты делаешь если несколько редюсеров должны среагировать на определенный экшн

Alexander
25.05.2016
13:16:31
и что ты делаешь если несколько редюсеров должны среагировать на определенный экшн
константы с префиксом также экспортируются и их можно использовать где угодно, в том числе в других редюсерах constants = { TOGGLE: prefix + '/TOGGLE', }

Страница 127 из 5115