how to set initial state in redux

前端 未结 4 1029
梦如初夏
梦如初夏 2020-12-03 04:07

I\'m trying to figure out how to set an initial state for a store in redux. I\'m using https://github.com/reactjs/redux/blob/master/examples/todos-with-undo/reducers/index.j

相关标签:
4条回答
  • 2020-12-03 04:45

    per @ctrlplusb answer, the reason this works is because

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

    the first todos is a key which sets the second todos as a return value from the reducer. Reducers always run one time upon store creation. This initializes your global store.

    There's an action dispatched when the store is created. That's how the initial state supplied in each combined reducer gets initialized in the store. If you check redux dev tools you'll see the first action dispatched is "@@redux/INIT{something}"

    In redux's documentation, near the end of the file, there is a dispatch({ type: ActionTypes.INIT })

    See here https://github.com/reduxjs/redux/blob/master/src/createStore.js#L281-L284

    See this question/answer I made on stackoverflow clarifying the response: Different ways of initializing a react redux store's initial global state?

    0 讨论(0)
  • 2020-12-03 04:47

    It needs to be the second argument to createStore:

    const rootReducer = combineReducers({
      todos: todos,
      visibilityFilter: visibilityFilter
    });
    
    const initialState = { 
      todos: [{id:123, text:'hello', completed: false}] 
    };
    
    const store = createStore(
      rootReducer, 
      initialState
    );
    
    0 讨论(0)
  • 2020-12-03 04:47

    You can set the initial state in the reducer(s).

    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
    })
    
    0 讨论(0)
  • 2020-12-03 05:03

    There have been great answers so far but let me ice the cake; perhaps to give you an in-depth analysis, so that you don't just copy StackOverflow codes``` that works but don't know why your program is working.

    There are two main ways to accomplish this viz: 1. using the createStore method. It takes an optional second argument (the preloadedState value)

    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
    

    if you call createStore without the preloadedState it would initialize the state to {} Hence the reducers will receive undefined as their state values. That brings us to the second method.

    1. You can set it at the reducers. Reducers can also set initialState by looking at the incoming state argument (which would be undefined if createStore is not called with initialState) and returning the values they would like to use as default.
    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
      }
    }
    

    The drawback of method 2 is evident in a case where there is huge data; like a huge todo list for instance that you want to pass as initialState "app-wide". Method 2 would bring in a lot of repetition as you would have to do the same thing across all your reducers. This is the main drawback. But it is quite popular when you just want to set initialState as {} it is a common pattern.

    Here is a 4min read for better understanding: https://dev.to/lawrence_eagles/how-to-properly-set-initial-state-in-redux-78m

    0 讨论(0)
提交回复
热议问题