
Антон
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
? я читал статью и мне нравится такой подход, но не пробовал ещё

Denis
25.05.2016
10:14:42

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:50:02

Alexander
25.05.2016
10:51:13

Евгений
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

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


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

Alexander
25.05.2016
12:46:10

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

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
стейт в редакс тащим не по своей воле. если к одному и тому же стейту нужен доступ из двух разных мест, то это оптимальный выбор
допустим есть табы со стейтом где хранится айди открытой табы, а есть где то фильтр этих табов совсем в другом месте и при активации фильтра надо сбрасывать индекса открытого таба на 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