简体   繁体   English

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

[英]More than one state property change in redux

I was using redux to check how it scales with my application. 我使用redux来检查它是如何随我的应用程序扩展的。 There are few things, that I found as roadblock when I was using it. 当我使用它时,我发现很少有东西可以作为障碍。 There are high possibility that I am not thinking the redux way / not using the way it was supposed to be used or have not read the doc properly. 很有可能我没有考虑使用redux方式/不使用它应该使用的方式或者没有正确阅读文档。 I have read the basic section this docs . 我已经阅读了本文档的基本部分。

The problem statement is fairly simple. 问题陈述相当简单。 I have two property in store 我在商店里有两处房产

{
    x: 10, 
    y: 20
}

lets say x is the x-position of the point and y is the y-position of the point. 假设x是点的x位置, y是点的y位置。 There is one condition if the x goes above 50, y value becomes equal to x. 如果x超过50,y值等于x,则有一个条件。

So I have this 所以我有这个

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

So the moment 那么一刻

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

is called the subscriber's function gets called twice hence the two times dom painting happen. 被称为订阅者的函数被调用两次因此两次dom绘画发生。

Is there a redux-way / workaround to solve this? 有没有一种redux-way / workaround来解决这个问题?

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. 您试图将xy作为相同子模型方程的一部分 - 当一个更新时,另一个也可能更新。

Using combineReducer you can update related state in the same reducer. 使用combineReducer可以在同一个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 . 根据Redux指南 ,如果你希望将状态分开,有时结合combineReducer是不够的,你可以将这种模式破坏成更公开的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. Redux中包含的combineReducers实用程序非常有用,但故意限于处理单个常见用例:通过将更新每个状态切片的工作委派给特定切片减速器来更新作为普通Javascript对象的状态树。 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. 它不处理其他用例,例如由Immutable.js Maps组成的状态树,尝试将状态树的其他部分作为附加参数传递给切片缩减器,或执行切片缩减器调用的“排序”。 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?". 那么,常见的问题是“我如何使用combineReducers来处理这些其他用例?”。 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. 一旦你超越了combineReducers的核心用例,就可以使用更多“自定义”的reducer逻辑,无论是一次性用例的特定逻辑,还是可以广泛共享的可重用函数。 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;
    }
}

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

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