Прочитать начальное состояние магазина в редукторе Redux



начальное состояние в приложении Redux может быть установлено двумя способами:




Если вы передаете начальное состояние в свой магазин, как Вы читаете это состояние из магазина и делаете его первым аргументом в своих редукторах?

664   4  

4 ответов:

TL; DR

без combineReducers() или аналогичный ручной код,initialState всегда побеждает state = ... в редукторе, потому что state перешел на редуктор иinitialState и неundefined, поэтому синтаксис аргумента ES6 в этом случае не применяется.

с combineReducers() поведение более тонкое. Те редукторы, состояние которых указано в initialState получите, что state. Другие редукторы получат undefinedи упадет обратно в state = ... аргумент по умолчанию они указывают.

в общем, initialState выигрывает над государством определенным редуктором. Это позволяет редукторам указывать исходные данные, которые имеют смысл в них как аргументы по умолчанию, но также позволяет загружать существующие данные (полностью или частично), когда вы увлажняющий магазин хранение ее в постоянном хранилище или сервер.

первый рассмотрим случай, когда у вас есть один редуктор.
Скажите, что вы не используете combineReducers().

затем ваш редуктор может выглядеть так:

function counter(state = 0, action) {
  switch (action.type) {
  case 'INCREMENT': return state + 1;
  case 'DECREMENT': return state - 1;
  default: return state;
  }
}

теперь предположим, что вы создаете магазин с ним.

import { createStore } from 'redux';
let store = createStore(counter);
console.log(store.getState()); // 0

начальное состояние равно нулю. Зачем? Потому что второй аргумент createStore был undefined. Это и есть state прошло к вашему редуктору в первый раз. Когда Redux инициализирует его, он отправляет "фиктивное" действие для заполнения состояния. Так что ваш counter редуктор был вызван с state равна undefined. это именно тот случай, который "активирует" аргумент по умолчанию. таким образом, state теперь 0 по умолчанию state значение (state = 0). Это состояние (0) будет возвращен.

давайте рассмотрим другой сценарий:

import { createStore } from 'redux';
let store = createStore(counter, 42);
console.log(store.getState()); // 42

почему 42, а не 0 на этот раз? Потому что createStore С 42 как второй аргумент. Этот аргумент становится state переданный к вашему редуктору вместе с фиктивным действием. в этот раз state не является неопределенным (это 42!), поэтому синтаксис аргумента по умолчанию ES6 не имеет никакого эффекта. The state и 42 и 42 возвращается из редуктора.


Теперь рассмотрим случай, когда вы используете combineReducers().
У вас есть два редуктора:

function a(state = 'lol', action) {
  return state;
}

function b(state = 'wat', action) {
  return state;
}

редуктор, созданный combineReducers({ a, b }) выглядит так:

// const combined = combineReducers({ a, b })
function combined(state = {}, action) {
  return {
    a: a(state.a, action),
    b: b(state.b, action)
  };
}

если мы называем createStore без initialState, он собирается инициализировать state до {}. Таким образом, state.a и state.b будет undefined к тому времени он называет a и b редукторы. и a и b редукторы получите undefined как ихstate Аргументы, и если они указывают default state значения, которые будут возвращены. вот как комбинированный редуктор возвращает a { a: 'lol', b: 'wat' } состояние объекта на первом вызов.

import { createStore } from 'redux';
let store = createStore(combined);
console.log(store.getState()); // { a: 'lol', b: 'wat' }

давайте рассмотрим другой сценарий:

import { createStore } from 'redux';
let store = createStore(combined, { a: 'horse' });
console.log(store.getState()); // { a: 'horse', b: 'wat' }

теперь я указал initialState в качестве аргумента createStore(). Состояние вернулось из комбинированного редуктора совместная начальное состояние, которое я указал для a редуктор с 'wat' аргумент по умолчанию указано, что b редуктор выбрал сам.

вспомним, что делает комбинированный редуктор:

// const combined = combineReducers({ a, b })
function combined(state = {}, action) {
  return {
    a: a(state.a, action),
    b: b(state.b, action)
  };
}

в этом случае state был указано, чтобы он не возвращался к {}. Это был объект с

в двух словах: это Redux тот, кто передает начальное состояние редукторам, вам ничего не нужно делать.

когда вы называете createStore(reducer, [initialState]) вы даете Redux знать, что такое начальное состояние, которое должно быть передано редуктору, когда приходит первое действие.

второй вариант, который вы упомянули, применяется только в том случае, если вы не прошли начальное состояние при создании магазина. то есть

function todoApp(state = initialState, action)

состояние будет инициализировано только в том случае, если его не было состояние передано Redux

Я надеюсь, что это ответ на ваш запрос (который я понял как инициализация редукторов при передаче intialState и возврате этого состояния)

вот как мы это делаем (предупреждение: скопировано из кода Typescript).

суть его в if(!state) тест в функции mainReducer (factory)

function getInitialState(): MainState {

     return {
         prop1:                 'value1',
         prop1:                 'value2',
         ...        
     }
}



const reducer = combineReducers(
    {
        main:     mainReducer( getInitialState() ),
        ...
    }
)



const mainReducer = ( initialState: MainState ): Reducer => {

    return ( state: MainState, action: Action ): MainState => {

        if ( !state ) {
            return initialState
        }

        console.log( 'Main reducer action: ', action ) 

        switch ( action.type ) {
            ....
        }
    }
}

как Вы читаете это состояние из магазина и делаете его первым аргументом в своих редукторах?

combineReducers () делают работу за вас. Первый способ написать это не очень полезно:

const rootReducer = combineReducers({ todos, users })

но другой, что эквивалентно более ясно:

function rootReducer(state, action) {
   todos: todos(state.todos, action),
   users: users(state.users, action)
}

Comments

    Ничего не найдено.