Redux Reducer:键注入状态

Redux Reducer: key injection into state

首先,我明白这是一个变异的状态变化;我知道我感到羞耻。有时正确的方法似乎不是最聪明的,或者至少我不知道更好的方法。

让我解释一下,我不想在不为预定义项目创建和交换旧状态和新状态的情况下将密钥注入我的状态。我只是想注入密钥一段时间,如果我不这样做,那么它们都会被清除。我的初始状态看起来像

{graphSite: {site: "default", graphBrowser: { graphID: '', graphKey:'' }, browsable:[] }};

我的减速器看起来像这样**使用 babel es7 对象传播运算符

case BROWSER: { state.graphSite.browsable[action.id] = action.payload
                return {...state}
               }

所以这会起作用,但是 redux 开发工具不显示状态变化,尽管可浏览数组是可访问的,这也许是因为我违背了规律,但如果我将更改扩展到:

case BROWSER:  { state.graphSite.browsable[action.id] = action.payload
                        return {...state, 
                                graphSite: {...state.graphSite, 
                                    graphBrowser: {...state.graphSite.graphBrowser},
                                    browsable: {...state.graphSite.browsable}   }
                                }
                            }

现在可浏览在工具中正确显示,但理想情况下,这些是同一件事。

所以问题是,对于不处于初始存储状态的动态键,操作状态的最佳方式是什么。这工作感觉就像我做错了什么,因为我操纵了原始状态。

一开始这个标题让我很困惑。 dynamic key injection 听起来对我来说太花哨了:P.

无论如何,您实际上想为您的 browserble 添加一对新的。 你有:

case BROWSER: { state.graphSite.browsable[action.id] = action.payload
            return {...state}
           }

这是错误的(假设 state 来自 reducer 参数),因为您是直接修改 state object。

redux 的一个原则就是Changes are made with pure functions。 (redux 文档).

FTFY:

case BROWSER: { 
  const nextState = JSON.parse(JSON.stringify(state)); // deep copy your state
  nextState.graphSite.browsable[action.id] = action.payload
  return nextState
}

这不是最有效的代码,JSON操作很昂贵。只是为了演示不直接改变状态 object 的原理。

好吧,我在对象传播的上下文中看不到如何附加变量键并且没有创建初始存储状态。在复制状态然后像这样返回附加后,这非常简单;两者都有效这个只是现在没有修改原始状态。

case BROWSER:  { let browser = {...state} 
                         browser.graphSite.browsable[action.id] = action.payload
                        return {...state, 
                                graphSite: {...state.graphSite, 
                                    graphBrowser: {...state.graphSite.graphBrowser},
                                    browsable: {...browser.graphSite.browsable}
                                    }
                                }
                            }

不对,谢谢你的反对票解构在这里很好用

case BROWSER:  { let {graphSite: {browsable: browser}} = state
                         browser[action.id] = action.payload

                        return {...state, 
                                graphSite: {...state.graphSite, 
                                    graphBrowser: {...state.graphSite.graphBrowser},
                                    browsable: {...browser}
                                    }
                                }
                            }

我也意识到我可以使用像 deepFreeze 或不可变的东西来检查这些但练习。