如何在 redux 中设置初始状态

how to set initial state in redux

我正在尝试弄清楚如何在 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

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

它需要是 createStore 的第二个参数:

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

const initialState = { 
  todos: [{id:123, text:'hello', completed: false}] 
};

const store = createStore(
  rootReducer, 
  initialState
);

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

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 的回答,之所以有效是因为

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

第一个 todos 是一个键,它将第二个 todos 设置为来自减速器的 return 值。 Reducers 总是 运行 一次创建商店。这将初始化您的全局存储。

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

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

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

看到这个 question/answer 我在 Whosebug 上做了澄清响应: Different ways of initializing a react redux store's initial global state?

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

有两种主要方法可以实现这一点: 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 {} 因此,reducer 将收到 undefined 作为它们的状态值。 这就把我们带到了第二种方法。

  1. 您可以在reducers处设置。 Reducers 也可以通过查看传入的 state argument (which would be undefined 来设置 initialState 如果 createStore 没有被 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 会带来很多重复,因为您必须在所有减速器上做同样的事情。这是主要缺点。但是当你只想设置 initialState as {} 时它很流行,这是一种常见的模式。

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