redux

时间:2017-05-16 08:12:07

标签: javascript redux

我使用redux来检查它与我的应用程序的比例。当我使用它时,我发现很少有东西可以作为障碍。 很有可能我没有考虑使用redux方式/不使用它应该使用的方式或者没有正确阅读文档。 我已阅读基本部分this docs

问题陈述相当简单。 我在商店里有两个房产

{
    x: 10, 
    y: 20
}

让我们说x是该点的x位置,y是该点的y位置。如果x超过50,y值等于x,则有一个条件。

所以我有这个

let x = (state = 10, action ) => {
    if (action.type === 'cx') {
        return action.value;
    }
    else {
        return state;
    }
}

let y = (state = 20, action ) => {
    if (action.type === 'cy') {
        return action.value;
    }
    else {
        return state;
    }
}

let model = redux.combineReducers({x: x, y: y});
let store = redux.createStore(model);

let actions = {
    changeX: (val) => {
        if ( val > 50) {
            store.dispatch(actions.changeY(val));
        }
        return {type: 'cx', value: val }
    },
    changeY: (val) => ({type: 'cy', value: val })
}

console.log('INITIAL STATE', '---', store.getState());

store.subscribe(() => {
    console.log('SUB2', '---', store.getState());
    // Paint the dom with new state
});

所以那一刻

store.dispatch(actions.changeX(60));

被称为订阅者的函数被调用两次因此两次dom绘画发生。

有解决这个问题的redux-way / workaround?

1 个答案:

答案 0 :(得分:2)

You are trying to relate to x and y as part of the same sub model equation - when one is updated, the other maybe updated also.

Using combineReducer you can update related state in the same reducer.

According to Redux guide, if you want that states to be separated, sometimes combineReducer is not enough, and you can breach that pattern into more openly reducer.

The combineReducers utility included with Redux is very useful, but is deliberately limited to handle a single common use case: updating a state tree that is a plain Javascript object, by delegating the work of updating each slice of state to a specific slice reducer. It does not handle other use cases, such as a state tree made up of Immutable.js Maps, trying to pass other portions of the state tree as an additional argument to a slice reducer, or performing "ordering" of slice reducer calls. It also does not care how a given slice reducer does its work.

The common question, then, is "How can I use combineReducers to handle these other use cases?". The answer to that is simply: "you don't - you probably need to use something else". Once you go past the core use case for combineReducers, it's time to use more "custom" reducer logic, whether it be specific logic for a one-off use case, or a reusable function that could be widely shared. Here's some suggestions for dealing with a couple of these typical use cases, but feel free to come up with your own approaches.

An example that is given related for this case:

function combinedReducer(state, action) {
    switch(action.type) {
        case "A_TYPICAL_ACTION" : {
            return {
                a : sliceReducerA(state.a, action),
                b : sliceReducerB(state.b, action)
            };
        }
        case "SOME_SPECIAL_ACTION" : {
            return {
                // specifically pass state.b as an additional argument
                a : sliceReducerA(state.a, action, state.b),
                b : sliceReducerB(state.b, action)
            }        
        }
        case "ANOTHER_SPECIAL_ACTION" : {
            return {
                a : sliceReducerA(state.a, action),
                // specifically pass the entire state as an additional argument
                b : sliceReducerB(state.b, action, state)
            }         
        }    
        default: return state;
    }
}