
Vitaly
09.11.2016
15:02:24
оке -_-

Yakov
09.11.2016
16:36:28
Коллеги, от куда лучше делать переход на новую страницу, типа history.push(). Т.е. в компоненте при нажатии на кнопку я делаю dispatch(action). Посылается запрос на сервер, если все ок, то нужно перейти на другую стр., а если ошибка, то возле кнопки появляется сообщение об ошибке. В какой части кода по феншую в этом случае сделать history.push?

Kir
09.11.2016
16:37:45
Парни, подскажите, как в реакте по клинку на кнопке занести данные в буфер обмена ?
Нужно именно по клику onCopy тут не походит как я понимаю

Google

Vladimir
09.11.2016
16:38:44
https://github.com/zenorocha/clipboard.js/

Pavel
09.11.2016
16:39:11

Kir
09.11.2016
16:39:36
@iamstarkov спасибо, а есть возможность без стороних библиотек это сделать ? во всем проекте нужно 1 строку скопировать, не хотелось бы засорять

Vladimir
09.11.2016
16:40:41
ну и его наверное на мдн можно найти

Kir
09.11.2016
16:41:40
Спасибо, сейчас гляну )

Yakov
09.11.2016
16:42:11

Ruslan
09.11.2016
16:42:31

Pavel
09.11.2016
16:42:44

Yakov
09.11.2016
16:43:13
а как этот push получить в action creator?

Pavel
09.11.2016
16:43:57
import { push } from 'react-router-redux'
dispatch(push(something))
но это если ты его используешь

Google

Pavel
09.11.2016
16:44:21
ну, этот роутер

Lupsick
09.11.2016
16:45:23
есть мнение что пихать урл в стейт тот еще маразм

Pavel
09.11.2016
16:45:24
кстати, пока отсылал, опять же проблема точки с запятой
вот серьезно, ну нахуя вы отказываетесь если забываете

Yakov
09.11.2016
16:45:42
а зачем делать dispatch(push(something)), почему не push(something)? разве push возвращает объект экшена?

Pavel
09.11.2016
16:46:44
https://github.com/reactjs/react-router-redux/blob/master/src/actions.js

Lupsick
09.11.2016
16:47:52

Pavel
09.11.2016
16:47:59

Lupsick
09.11.2016
16:48:08

Yakov
09.11.2016
16:49:50

Pavel
09.11.2016
16:50:18

Yakov
09.11.2016
16:50:35
а, сек. посмотрю


Bogdan
09.11.2016
17:23:18
Народ а что вы думаете по поводу того что redux пропагандирует какой-то "view driven design"? - когда мы начинаем разрабатывать исходя из того как данные отображаются на экране или должны отобразится после какого-то действия - получаем кучу всяких акшинов BUTTON_CLICKED ,
export const CHANGE_ACTIVE_USER_ID = 'CHANGE_ACTIVE_USER_ID';
export const CHANGE_CURRENT_TIME = 'CHANGE_CURRENT_TIME';
export const CHANGE_IS_MOBILE = 'CHANGE_IS_MOBILE';
export const CHANGE_MODAL = 'CHANGE_MODAL';
export const CHANGE_PATH = 'CHANGE_PATH';
export const CHANGE_PLAYING_SONG = 'CHANGE_PLAYING_SONG';
export const CHANGE_SELECTED_PLAYLISTS = 'CHANGE_SELECTED_PLAYLISTS';
export const CHANGE_WIDTH_AND_HEIGHT = 'CHANGE_WIDTH_AND_HEIGHT';и в редюсерах мы обрабатываем все это как потребности наших вьюх.Для маленьких приложений такой подход прекрасно работает но при попытке разработать что-то сложное получается месиво из акшинов TASK_ADDED, TASK_DELETED, TASK_COMPLETED, TASK_RECIEVED на каждый тип сущности когда совершенно логически и естественно хочется выделить все эти акшины в три вида ADD,UPDATE, DELETE и думать в контексте сущностей а не событий.
А есть кажется другой подход который кажется называется domain driven design ("DDD"), - который говорит что всю бизнес-логику мы должны сначала разрабатывать в чистом вакууме моделируя сущности как объекты и связи между ними и обрабатывать все изменения состояния в этих моделях через изменения самих объектов (ADD, UPDATE, DELETE). И только потом уже спускаться к отображению на компонентах и вьюхах, будь то мобилки или обычные сайты. То есть бизнес-сущностей может быть совсем немного - юзер, борд, пост, картика, комментарий а вот разнообразного количества того как это все должно отображаться, обновляться в компонентах вот это уже может быть бесконечное количество, но главное что сущности и бизнес-логика сущностей и связей (one-to-many, many-to-many) и совершенно не меняется, меняется только различная привязка и обработка этих данных только по требованию самих компонентов
Я думаю второй подход лучше маштабируется при разработке сложных приложений


Дима
09.11.2016
17:28:12
Ну ты забываешь что Redux это только View, бизнес-логику туда тянуть не надо

Pavel
09.11.2016
17:28:46
даже не знаю что лучше, вопрос или ответ


Vladimir
09.11.2016
17:28:49
Народ а что вы думаете по поводу того что redux пропагандирует какой-то "view driven design"? - когда мы начинаем разрабатывать исходя из того как данные отображаются на экране или должны отобразится после какого-то действия - получаем кучу всяких акшинов BUTTON_CLICKED ,
export const CHANGE_ACTIVE_USER_ID = 'CHANGE_ACTIVE_USER_ID';
export const CHANGE_CURRENT_TIME = 'CHANGE_CURRENT_TIME';
export const CHANGE_IS_MOBILE = 'CHANGE_IS_MOBILE';
export const CHANGE_MODAL = 'CHANGE_MODAL';
export const CHANGE_PATH = 'CHANGE_PATH';
export const CHANGE_PLAYING_SONG = 'CHANGE_PLAYING_SONG';
export const CHANGE_SELECTED_PLAYLISTS = 'CHANGE_SELECTED_PLAYLISTS';
export const CHANGE_WIDTH_AND_HEIGHT = 'CHANGE_WIDTH_AND_HEIGHT';и в редюсерах мы обрабатываем все это как потребности наших вьюх.Для маленьких приложений такой подход прекрасно работает но при попытке разработать что-то сложное получается месиво из акшинов TASK_ADDED, TASK_DELETED, TASK_COMPLETED, TASK_RECIEVED на каждый тип сущности когда совершенно логически и естественно хочется выделить все эти акшины в три вида ADD,UPDATE, DELETE и думать в контексте сущностей а не событий.
А есть кажется другой подход который кажется называется domain driven design ("DDD"), - который говорит что всю бизнес-логику мы должны сначала разрабатывать в чистом вакууме моделируя сущности как объекты и связи между ними и обрабатывать все изменения состояния в этих моделях через изменения самих объектов (ADD, UPDATE, DELETE). И только потом уже спускаться к отображению на компонентах и вьюхах, будь то мобилки или обычные сайты. То есть бизнес-сущностей может быть совсем немного - юзер, борд, пост, картика, комментарий а вот разнообразного количества того как это все должно отображаться, обновляться в компонентах вот это уже может быть бесконечное количество, но главное что сущности и бизнес-логика сущностей и связей (one-to-many, many-to-many) и совершенно не меняется, меняется только различная привязка и обработка этих данных только по требованию самих компонентов
Я думаю второй подход лучше маштабируется при разработке сложных приложений
> Народ а что вы думаете по поводу того что redux пропагандирует какой-то "view driven design"?
react+redux это как раз про state+view
как ты верхние уровни абстракции организуешь зависит от тебя, а не от редакса


Aleh
09.11.2016
17:30:36
redux только view O.o

Pavel
09.11.2016
17:34:19
стоит обратить внимание что реакт и редакс вполне себе отлично существуют друг без друга

Google

Aleh
09.11.2016
17:37:11
идея и тулзы, которые дает редакс очень подходят к ddd. Вы проводите анализ того, что у вас в системе вообще происходит(event storming) и как оно все связано. Т.е. редьюсеры производят только то, что надо вьюхе это правда, они read-model
но сам cqrs вполне норм позволяет делать ddd

Vitaly
09.11.2016
17:43:35
Мне кажется кто-то любит все усложнять и абстрагировать...
Самый частый кейс в том что браузер - интерфейс ввода и вывода информации из базы данных, все. Ваша задача взять поток данных, нормализовать и визуализировать его.


Bogdan
09.11.2016
17:44:54
Просто проблема в том что с редаксом я не могу хранить состояние в виде объектов и связей между ними и моделировать бизнес-логику согласно DDD
class User {
id;
posts = [];
comments = [];
constructor(data){Object.assign(this, data)}
}
class Post {
id;
comments = [];
user;
constructor(data){Object.assign(this, data)}
}
class Comment {
id;
user;
constructor(data){Object.assign(this, data)}
}
var user = new User({id: 'user1', posts: [], comments: []})
var post = new Post({id: 'post1', user: user, comments: []})
user.posts.push(post);
var comment = new Comment({id: 'comment1', post: post, user: user})
post.coments.push(comment)
user.comments.push(comment)и потом где-то в редюсере
state = {user: user}
потому что получаются циклические ссылки из-за чего требование вернуть новый иммутабельный объект состояния в редаксе выльется в генерацию новых объектов всего состояния

Исмаил
09.11.2016
17:45:57
Так может не использовать его для того, для чего он не предназначен?

Vasiliy
09.11.2016
17:47:17
не надо так делать, нужно много думать и читать, пока не надо ничего писать

Vitaly
09.11.2016
17:47:19
А в чем проблема использовать Immutable.Record?

Aleh
09.11.2016
17:52:28
все твои связи во write-model
как ты ее организуешь redux не регламентирует(как хочешь)
при этом скорее всего на клиенте тебе как таковая write-model не понадобится. Имею ввиду как принято делать в java/c#/php persist-ignor entity, которые вотчаться через UoW и собираются в единую транзакцию. Такое на клиенте не делается в силу отсутствия транзакций и смысла


Bogdan
09.11.2016
18:05:04
что захламляет логику


Aleh
09.11.2016
18:10:20
state - read-model
его надо формировать так, чтобы можно было удобнее всего выводить, считай что эот ваши dto для отображения, готовые
не понял, вы диспатчите какие-то гетеры?
ну, а react-redux с connect чем не подошел?

Bogdan
09.11.2016
18:18:23
ну, а react-redux с connect чем не подошел?
в mapStateToProps я вытаскиваю только то что нужно для отображения. А обработчикам событий требуются больше информации. Если выписывать все необходимое в mapStateToProps то будет постоянный перендер на каждое обновления. Для того чтобы получить в обработчике какие-то объекты по айдишнику приходится диспатчить thunk который получает доступ к состоянию - dispatch((_, getState)=>getState().tables.tasks[taskId])

Google

Aleh
09.11.2016
18:18:49
ну у вас read-model плохой
почему ему нужно что-то, чего ему не дает view

Vitaly
09.11.2016
18:19:29

Aleh
09.11.2016
18:19:59
ну, это не железное правило, иногда так действительно может быть проще, мол докинуть еще параметр

Dmitry
09.11.2016
18:33:57
Почитай про cqrs

Bogdan
09.11.2016
19:00:24
С cqrs мы и получаем такой разброс событий -
CHANGE_ACTIVE_USER_ID
CHANGE_CURRENT_TIME
CHANGE_IS_MOBILE
CHANGE_MODAL
CHANGE_PATH
CHANGE_PLAYING_SONG
CHANGE_SELECTED_PLAYLISTS
CHANGE_WIDTH_AND_HEIGHT
и на каждой тип свой action-creator и свой редюсер. Получаем кучу болерплейта для обычного crud-а. А если бы моделировали логику через сущности то из всех этих событий можно выделить что-то общее CHANGE_ACTIVE_USER_ID это обновление поля у сущности user, CHANGE_CURRENT_TIME это обновление другой сущности и т.д. И можно написать всего один редюсер который будет принимать всего три типа ADD, UPDATE, DELETE, а в параметрах тип сущности и айдишник и что обновить или создать, таким образом избавимся от кучи болеплейта

Pavel
09.11.2016
19:01:30
multireducer
обертки
и тд
вот что-что, но в редаксе бойлерплейт наплодить надо постараться

Артем
09.11.2016
19:12:47
по ангулару есть такой чатик?

Bogdan
09.11.2016
19:19:16

Aleh
09.11.2016
19:19:51
С cqrs мы и получаем такой разброс событий -
CHANGE_ACTIVE_USER_ID
CHANGE_CURRENT_TIME
CHANGE_IS_MOBILE
CHANGE_MODAL
CHANGE_PATH
CHANGE_PLAYING_SONG
CHANGE_SELECTED_PLAYLISTS
CHANGE_WIDTH_AND_HEIGHT
и на каждой тип свой action-creator и свой редюсер. Получаем кучу болерплейта для обычного crud-а. А если бы моделировали логику через сущности то из всех этих событий можно выделить что-то общее CHANGE_ACTIVE_USER_ID это обновление поля у сущности user, CHANGE_CURRENT_TIME это обновление другой сущности и т.д. И можно написать всего один редюсер который будет принимать всего три типа ADD, UPDATE, DELETE, а в параметрах тип сущности и айдишник и что обновить или создать, таким образом избавимся от кучи болеплейта
ну так называйте их правильнее, PLAY_SONG, SELECT_PLAYLIST. Ну и если вы crud хотите, а не ddd, то да, делайте общий редьюсер, creator и не парьтесь

♥️
09.11.2016
19:23:26
доброго вечера!
вебпак собирает путь вида "/folder/file" мне нужно "./folder/file"

Владислав
09.11.2016
19:28:10

♥️
09.11.2016
19:45:29
prod build делает сжатое все
и вот
в index.html
все пути к css и js лежат абсолютно

Arsen
09.11.2016
20:10:39
Привет всем. Пытаю редакс. Помогите разобраться в проблеме одинакого стейта между экшионами.

Google


Arsen
09.11.2016
20:11:16
Есть компонента у которой есть инпат:
<input type="text" name="first-name" placeholder="Введите имя проекта здесь." value={this.props.newProjectName} onChange={this.newProjectNameChange} />
На изменение которого повесил обработчик который диспатчит новой состояние в стор:
newProjectNameChange = (e) => {
e.preventDefault();
store.dispatch(newProjectNameChanged(e.target.value));
}
Вот так выглядит функция формирующая экшен:
export function newProjectNameChanged(data) {
return {
type: NEW_PROJECT_NAME_CHANGED,
data: data
}
}
Вот код редьюсера:
import actions from './actions';
const reducer = (state, action) => {
switch (action.type) {
case actions.ADD_NEW_PROJECT:
return {
...state,
projects: projects.push(action.data)
}
case actions.CHANGE_PROJECT:
return {
...state,
currentProject: action.data
}
case actions.NEW_PROJECT_NAME_CHANGED:
console.log(action);
return {
...state,
newProjectName: action.data
}
case actions.NEW_PROJECT_DESCRIPTION_CHANGED:
return {
...state,
newProjectDescription: action.data
}
default:
return state
}
}
export default reducer
ну и естественно все это засылаю в стор:
import { createStore, combineReducers } from 'redux';
import { Router, Route, browserHistory } from 'react-router';
import { syncHistoryWithStore, routerReducer } from 'react-router-redux';
import reducers from './reducers';
const store = createStore(
combineReducers({
...reducers,
routing: routerReducer
}),
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
)
const history = syncHistoryWithStore(browserHistory, store)
export default store;
====
Ввожу какие-нибудь значения в поле на котором висит обработчик - в redux-dev-tools видно что экшен кидается - но если смотреть diff между предыдущим стэйтом и текущим - нету разницы. То есть я в редюсерах вместо копирования и изменения копии стэйта изменяю сам стейт? Нарушается его "иммутабельность" и диффа в итоге нет? Или я снаркоманился и вообще не в этом причина? Оператор расширения использовал так как это показывают в примерах


S
09.11.2016
20:19:32


Vitaly
09.11.2016
20:19:54

Arsen
09.11.2016
20:20:30
@bitaru сейчас гляну, забыл про него