如何通过迭代使用不可变原理更新redux状态的每个键

时间:2017-06-04 16:01:17

标签: reactjs redux react-redux reselect

我有一个redux状态如下: -

data = {"facebook":true,"twitter":false,"google":false,"instagram":false,"watsapp":false}

我将在行动中传递关键值: - (" facebook"," twitter")

让我说我通过" facebook"。 然后我希望状态更新为

{"facebook":true,"twitter":false,"google":false,"instagram":false,"watsapp":false}

这是我的减速器功能

function data = (state=initialstate,action) => {
   return {...state, [action.account]=true}
}

第一次,它会给出理想的结果。

{"facebook":true,"twitter":false,"google":false,"instagram":false,"watsapp":false}

现在让我们说,我正在传递密钥" twitter"

我想要的是什么:

{"facebook":false,"twitter":true,"google":false,"instagram":false,"watsapp":false}

我在减速器功能上面得到了什么(正如预期的那样)

{"facebook":true,"twitter":true,"google":false,"instagram":false,"watsapp":false}

所以我将reducer功能更新为: -

function data = (state, action) => {
  Object.keys(state).forEach(function(key) {
    if(key!=action.account){
      state[key]=false; 
    } else {
      state[key]=true; 
    }
   });
  return state
}

但这是针对不可变数据的redux原则。 当我使用选择器时,它显示出一些意想不到的行为。

如何更新我的reducer函数,它将所有先前设置的值设置为 false ,并且只将当前键设置为 true ,同时记住redux的不可变数据原理

3 个答案:

答案 0 :(得分:1)

根据我的理解,您希望将所有密钥设置为false,但已将已发送的action.account设置为true

const data = (state, action) => {
    let { account } = action
    var newObj = {}

    Object.keys(state).forEach(function(key) {
        newObj[key] = false
    })

    return {...newObj, [account]:true }
}

答案 1 :(得分:0)

如果您正在使用Underscore * ,则可以使用_.map(state, (v, k) => /* logic that returns true/false */)生成新的state实例,同时保持上一个不变。

请注意,感觉更好的数据模型可能只是在您的州中存储单个字符串,对应于“当前”帐户。

*使用Object.entries()....可以实现等效行为,但这很严重,我不想弄明白:)

答案 2 :(得分:0)

简单地说,使用新的空对象而不是修改原始状态对象。

function data = (state, action) => {
  const newState = {};
  Object.keys(state).forEach(function(key) {
    if(key!=action.account){
      newState[key]=false; 
    } else {
      newState[key]=true; 
    }
   });
  return newState
}