Я начал изучать реакцию-redux-immutable пару дней назад, и я все еще довольно запутался в структурировании моего приложения. У меня есть php (symfony/laravel MVC background), поэтому не легко понять мою концепцию javascript.
1) У меня есть строки WrapperComponent:
export default function (props) {
const style = {position: "relative"};
const lines = props.lines;
return (
<div className='wrapper' style={style}>
{lines.map(line => (
<Line key={line.get("id")} {...line.toObject()} />
))}
<Board />
</div>
);
}
2) Это связано с WrapperContainer
import Wrapper from '../components/WrapperComponent';
export default connect(
function mapStateToProps(state) {
return {
lines: state.lines.map(line => {
return line.set("board", {
width: state.board.get("width"),
height: state.board.get("height")
});
})
};
},
function mapDispatchToProps(dispatch) {
return {};
}
)(Wrapper);
3) Затем выполняется действие addLine
export function addLine(type) {
return {
type: types.ADD_LINE,
payload: {
id: 3, top: 0, left: 0, diffX: 0, diffY: 0, type: type, board: {
width: 0,
height: 0
}, active: false
}
};
}
4) Это говорит о LinesReducer
export default function LinesReducer(state = initialState, action) {
switch (action.type) {
case types.ADD_LINE:
return state.push(
Map(action.payload)
);
default:
return state;
}
}
5) Чтобы WrapperContainer мог прослушивать изменения состояния и повторно отображать строки
export default connect(
function mapStateToProps(state) {
return {
lines: state.lines.map(line => {
return line.set("board", {
width: state.board.get("width"),
height: state.board.get("height")
});
})
};
},
function mapDispatchToProps(dispatch) {
return {};
}
)(Wrapper);
Теперь мой вопрос:
Где я могу поместить логику относительно действия addLine?
Когда я создаю строку, я хочу установить ее идентификатор И я хочу установить его ширину так же, как ширина/высота другого компонента.
Я предполагаю, что действия должны передавать только информацию из одного места в другое.
Тогда я думаю... может быть, логика должна жить в LinesReducer. Но Lines редуктор не имеет доступа к глобальному состоянию приложения, поэтому я не знаю, какую ширину/высоту должна иметь новая строка.
Тогда есть WrapperContainer. Контейнер имеет информацию о состоянии всего приложения, поэтому представляется целесообразным прокручивать каждую строку и устанавливать идентификаторы, если они не установлены, и обновлять их ширину/высоту и другую информацию.
Но это не кажется мне правильным. Я думал об одном месте, которое собирало информацию о глобальном состоянии приложения, тогда оно добавило бы новую строку на основе этой информации, и ничто другое не коснется этой строки еще раз. За исключением другого действия.
Это правильный подход? Я действительно хочу изменить ширину/высоту линии, когда изменится другая высота/ширина компонента, поэтому контейнер имеет для меня наибольший смысл.
EDIT:
Может быть:
1) установите ID в действии, когда строка фактически создана (я просто не знаю, сколько строк уже есть, поэтому я действительно не знаю, какой ID я должен установить)
2) установите ширину/высоту в контейнере, когда он передает строки в реквизиты (но если я в конечном итоге захочу отобразить строки в другом контейнере, мне придется дублировать код там, если я не создаю какую-либо "глобальную" функцию, которая обрабатывает передачу линии к компонентам в контейнерах)
Вы должны сохранить свои редукторы как чистые функции. Это означает, что если вы вызовете их несколько раз с теми же аргументами, они будут иметь одинаковый ожидаемый результат, зависящий только от аргументов.
Тем не менее, место, в которое вы должны поместить этот тип логики, называется action creator, который на самом деле является вашей функцией addLine
.
Создатели Action - это именно те функции, которые создают действия. Легко скомпоновать термины "действие" и "создатель действия", поэтому сделайте все возможное, чтобы использовать правильный термин.
Создатели действий также могут быть асинхронными и иметь побочные эффекты.
Подробнее в docs
Создатели Action могут знать ваше текущее состояние, добавляя некоторое промежуточное ПО, например redux-thunk:
Средство промежуточного ПО Redux Thunk позволяет писать создателей действий, которые возвращают функцию вместо действия. Thunk может использоваться для задержки отправки действия или для отправки только в том случае, если выполняется определенное условие. Внутренняя функция получает параметры хранилища dispatch и getState в качестве параметров.
redux-thunk
. Создатель действияfetchUser
имеет доступ кgetState
, из которого он должен знать о строках.