【问题标题】:how to set initial state in redux如何在 redux 中设置初始状态
【发布时间】:2016-10-15 20:13:01
【问题描述】:

我试图弄清楚如何在 redux 中为商店设置初始状态。我以https://github.com/reactjs/redux/blob/master/examples/todos-with-undo/reducers/index.js 为例。我尝试修改代码,使待办事项具有初始化的值。

const todoApp = combineReducers({
  todos,
  visibilityFilter
}, {
  todos: [{id:123, text:'hello', completed: false}]
})

关注文档:http://redux.js.org/docs/api/createStore.html

但它不起作用,我不太清楚为什么。

【问题讨论】:

    标签: reactjs redux react-redux


    【解决方案1】:

    到目前为止,已经有了很好的答案,但让我来冰蛋糕吧;也许是为了给你一个深入的分析,这样你就不会只是复制 StackOverflow 代码``` 工作但不知道你的程序为什么工作。

    有两种主要方法可以完成此即: 1.使用createStore方法。它需要一个可选的第二个参数(preloadedState 值)

    const store = createStore(counter) // createStore without preloadedState
    const initialState = {} // or in your case:
    const initialState = {
                             initialTodos = [{id:123, text:'hello', completed: false}]
                         }
    const store = createStore(counter, initialState) // create store with preloadedState
    

    如果您在没有 preloadedState 的情况下调用 createStore,它将初始化 state to {} 因此,reducers 将收到undefined 作为它们的状态值。 这就引出了第二种方法。

    1. 您可以将其设置为reducersReducers 也可以通过查看传入的 state argument (which would be undefined(如果 createStore 未使用 initialState 调用)并返回他们希望用作默认值的值来设置 initialState
    const initialState = {} // a common pattern but in your case:
    const initialState = {
                             initialTodos = [{id:123, text:'hello', completed: false}]
                         }
    function todoReducer(state = initialState, action) {
      switch (action.type) {
        case // your type:
          return ...
        default:
          return state
      }
    }
    

    方法2的缺点在数据量很大的情况下很明显;就像一个巨大的待办事项列表,例如你想作为initialState“app-wide”传递。方法 2 会带来很多重复,因为您必须在所有 reducer 上做同样的事情。这是主要缺点。但是当您只想设置initialState as {} 时,它很受欢迎,这是一种常见的模式。

    为了更好地理解,请阅读 4 分钟:https://dev.to/lawrence_eagles/how-to-properly-set-initial-state-in-redux-78m

    【讨论】:

      【解决方案2】:

      根据@ctrlplusb 的回答,这样做的原因是因为

      const rootReducer = combineReducers({
        todos: todos,
        visibilityFilter: visibilityFilter
      });
      

      第一个todos 是一个键,它将第二个todos 设置为reducer 的返回值。 Reducer 总是在 store 创建时运行一次。这将初始化您的全局存储。

      在创建商店时调度了一个操作。这就是每个组合 reducer 中提供的初始状态如何在 store 中初始化的方式。如果您检查 redux 开发工具,您会看到调度的第一个操作是“@@redux/INIT{something}”

      在redux的文档中,在文件末尾附近,有一个dispatch({ type: ActionTypes.INIT })

      请看这里https://github.com/reduxjs/redux/blob/master/src/createStore.js#L281-L284

      请参阅我在 stackoverflow 上提出的这个问题/答案,以澄清响应: Different ways of initializing a react redux store's initial global state?

      【讨论】:

      • github 链接已失效。您可能应该链接到实际提交而不是某个分支,因为这些可以得到更新。
      【解决方案3】:

      它必须是createStore 的第二个参数:

      const rootReducer = combineReducers({
        todos: todos,
        visibilityFilter: visibilityFilter
      });
      
      const initialState = { 
        todos: [{id:123, text:'hello', completed: false}] 
      };
      
      const store = createStore(
        rootReducer, 
        initialState
      );
      

      【讨论】:

      • 如果我没有在 reducer 中指定默认状态值并将初始状态提供给createStore,则状态设置不正确。
      【解决方案4】:

      您可以在减速器中设置初始状态。

      const initialTodos = [{id:123, text:'hello', completed: false}]
      
      // this is the ES2015 syntax for setting a default value for state in the function parameters
      function todoReducer(state = initialTodos, action) {
        switch(action.type) {
          ... 
        }
        return state
      }
      
      
      const todoApp = combineReducers({
        // todos now defaults to the array of todos that you wanted and will be updated when you pass a new set of todos to the todoReducer
        todos: todoReducer,
        visibilityFilter
      })
      

      【讨论】:

      • 有什么理由比这个更喜欢@ctrlplusb 吗?
      • jmancherje 的其实是 redux 推荐的:redux.js.org/recipes/structuring-reducers/…
      • 是的,您绝对应该在减速器上定义默认状态,我只是认为 OP 正在寻找与完全存储补液相关的解决方案(例如 SSR / localstorage)。
      猜你喜欢
      • 2021-03-10
      • 1970-01-01
      • 2021-06-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-27
      • 2017-09-01
      相关资源
      最近更新 更多