Ответственность React Redux

Я начал изучать react-redux-immutable пару дней назад и до сих пор не совсем понимаю, как структурировать свое приложение. У меня есть php (фон Symfony/laravel MVC), поэтому мне нелегко понять некоторые концепции 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. Контейнер имеет информацию о состоянии всего приложения, поэтому кажется разумным перебирать каждую строку и устанавливать идентификаторы, если они не установлены, и обновлять их ширину/высоту и другую информацию.

Но мне это не кажется правильным. Я думал об одном месте, которое будет собирать информацию о глобальном состоянии приложения, а затем добавлять новую строку на основе этой информации, и ничто больше никогда не коснется этой строки снова. Кроме другого действия.

Это правильный подход? Я действительно хочу изменить ширину/высоту линии, когда изменяется высота/ширина другого компонента, поэтому контейнер имеет для меня наибольший смысл.

ИЗМЕНИТЬ:

Может быть:

1) установить идентификатор в действии, когда линия фактически создана (я просто не знаю, сколько строк уже существует, поэтому я действительно не знаю, какой идентификатор я должен установить)

2) установить ширину/высоту в контейнере, когда он передает строки в реквизит (но если я в конечном итоге захочу отобразить строки в другом контейнере, мне придется дублировать там код, если я не создам какую-то «глобальную» функцию, которая обрабатывает передачу строк в компонент реквизит в контейнерах)


person Michal    schedule 19.06.2016    source источник


Ответы (1)


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

Тем не менее, место, которое вы должны поместить в этот тип логики, называется создатель действия, что на самом деле является вашей addLine функцией.

Создатели действий — это именно те функции, которые создают действия. Термины «действие» и «создатель действия» легко смешать, поэтому постарайтесь использовать правильный термин.

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

Узнайте больше в документах.

Создатели действий могут быть в курсе вашего текущего состояния, добавив промежуточное ПО, такое как redux-thunk:

Промежуточное ПО Redux Thunk позволяет вам писать генераторы действий, которые возвращают функцию вместо действия. Преобразователь можно использовать для задержки отправки действия или для отправки только при выполнении определенного условия. Внутренняя функция получает в качестве параметров методы store и getState.

person Diego Haz    schedule 19.06.2016
comment
Хорошо, спасибо. :) Но если у меня есть, скажем, 5 строк. Я хочу добавить 6-й. ActionCreator не знает, сколько строк в приложении. Как установить идентификатор новой строки? (я хочу, чтобы это было 6) Также я хочу установить ширину всех строк так же, как ширина другого компонента в моем приложении. Опять actionCreator не знает, какую информацию устанавливать. - person Michal; 20.06.2016
comment
Ваш создатель действия не знает, но вы можете использовать промежуточное программное обеспечение, чтобы ваши создатели действий знали о текущем состоянии. Взгляните на этот пример, используя redux-thunk. Создатель действия fetchUser имеет доступ к getState, откуда он должен знать о строках. - person Diego Haz; 20.06.2016
comment
Спасибо, я попробую это. :) - person Michal; 20.06.2016