繁体   English   中英

redux中不止一个州的财产变化

[英]More than one state property change in redux

我使用redux来检查它是如何随我的应用程序扩展的。 当我使用它时,我发现很少有东西可以作为障碍。 很有可能我没有考虑使用redux方式/不使用它应该使用的方式或者没有正确阅读文档。 我已经阅读了本文档的基本部分。

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

{
    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来解决这个问题?

您试图将xy作为相同子模型方程的一部分 - 当一个更新时,另一个也可能更新。

使用combineReducer可以在同一个reducer中更新相关状态。

根据Redux指南 ,如果你希望将状态分开,有时结合combineReducer是不够的,你可以将这种模式破坏成更公开的reducer

Redux中包含的combineReducers实用程序非常有用,但故意限于处理单个常见用例:通过将更新每个状态切片的工作委派给特定切片减速器来更新作为普通Javascript对象的状态树。 它不处理其他用例,例如由Immutable.js Maps组成的状态树,尝试将状态树的其他部分作为附加参数传递给切片缩减器,或执行切片缩减器调用的“排序”。 它也不关心给定的切片减速器如何工作。

那么,常见的问题是“我如何使用combineReducers来处理这些其他用例?”。 答案很简单:“你没有 - 你可能需要使用别的东西”。 一旦你超越了combineReducers的核心用例,就可以使用更多“自定义”的reducer逻辑,无论是一次性用例的特定逻辑,还是可以广泛共享的可重用函数。 以下是处理几个典型用例的一些建议,但您可以随意提出自己的方法。

给出了与此案例相关的示例:

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;
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM