1

我的 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}

所以我更新了我的减速器功能如下: -

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的不可变数据原则

4

3 回答 3

2

据我了解,您希望所有键都设置为false,除了 dispatchedaction.account设置为true

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

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

    return {...newObj, [account]:true }
}
于 2017-06-04T21:57:46.407 回答
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
}
于 2017-06-04T16:16:54.393 回答
0

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

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


* 使用 可以实现等效行为Object.entries()....,但它很糟糕,我不想弄清楚 :)

于 2017-06-04T16:08:00.827 回答