Путаница с тем, как createStore работает в Redux - PullRequest
3 голосов
/ 02 мая 2020

Я изучал Redux и наткнулся на функцию createStore. Итак, как я понял, createStore получает 3 параметра:

reducer
initial state
enhancers (for simplicity we will use only middlewares)

Но когда мы используем createStore в действии, мы не передаем начальное состояние в качестве второго аргумента, НО передаем редуктор с состоянием по умолчанию, например:

const initialState = {counter:0}
const reducer =(state=initialState, action)=>...

Вопрос в том, почему мы не помещаем начальное состояние в качестве второго аргумента, а передаем initialState редуктору?

Ответы [ 3 ]

1 голос
/ 02 мая 2020

Я думаю, что вы путаете initial состояние редуктора с глобальным состоянием вашего приложения.

Глобальное состояние означает просто объединенное состояние всех редукторов в вашем приложении.

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

Редуктор:

function todos(state = [], action) {
  switch (action.type) {
    case 'ADD_TODO':
      return state.concat([action.text])
    default:
      return state
  }
}

Так что эта простая функция todos - это наш редуктор, который даст нам текущее дерево состояний, когда бы оно ни выполнялось.

Так что это наш первый параметр для createStore.

Начальное состояние:

['Understanding Store']

Давайте предположим, что наше начальное укажите как массив, который содержит 1 элемент, как показано выше.

Это будет наш второй параметр для createStore.

Теперь мы создадим наш магазин следующим образом:

import { createStore } from 'redux'

//... code
.
.
.
const store = createStore(todos, ['Understanding Store'])

Теперь наш магазин создан. Ничего особенного, store - это, по сути, объект, в котором есть несколько методов.

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

Поэтому, когда мы делаем это

store.dispatch({
  type: 'ADD_TODO',
  text: 'Learn methods on Store'
})

, это обновит наше состояние, как показано ниже:

['Understanding Store','Learn methods on Store']

Но когда ваше приложение становится большим, вы можете захотеть создать разные функции (редукторы) для управления различными частями вашего глобального состояния.

Если у нас есть еще один редуктор, скажем counter.js:

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

}

Затем, чтобы объединить наши 1-ые задачи редуктора и этот счетчик-редуктор, у нас есть утилита под названием combineReducer.

rootReducer. js

import { combineReducers } from 'redux'
import todos from './todos'
import counter from './counter'

export default combineReducers({
  todos,
  counter
})

Затем, используя createStore, вы просто делаете это:

import { createStore } from 'redux'
import rootReducer from './rootReducer.js;

const store = createStore(rootReducer);

Существуют определенные правила, которым необходимо следовать при использовании combineReducers.

Ознакомьтесь с правилами здесь

1 голос
/ 02 мая 2020

Я думаю, что вы на самом деле перепутали createStore с редуктором. Представьте, что createStore представляет собой функцию, которая возвращает вам набор редукторов, добавляя в него некоторые промежуточные компоненты и другие функции, такие как dispatch

. Чаще всего в вашем приложении есть несколько редукторов, и вы фактически комбинируете их, используя combineReducers

Скажем, например, что вы объединяетеReducers:

import userReducer from 'reducers/user';
import authReducer from 'reducers/auth';
import countReducer from 'reducers/count';
const reducers = combineReducers({
   userReducer,
   authReducer,
   countReducer,
});

Теперь initialState для createStore должен иметь формат объекта с ключами как userReducer, authReducer, countReducer, а затем состояние отдельных редукторов. Например,

{
   userReducer: { id: 1, name: 'Test'},
   authReducer: { isLoading: true, isAuthenticated: false},
   countReducer: {counter: 0}
}

Теперь вещь из вторых ключей эквивалентна initialState каждого отдельного редуктора

Например: редуктор / счет. js

const initialState = {counter:0}
const reducer =(state=initialState, action)=>...

это работает так, что createStore будет фактически вызывать редуктор с действием каждый раз, когда действие вызывается, как

reducer(state, action);

В случае combReducer это работает как показано ниже

const combineReducers = (reducers) => {
    return (state, action) => {
        const tempState = { ...state };
        Object.keys(reducers).forEach((key) => {
            tempState[key] = reducers[key](tempState[key], action);
        });
        return tempState;
    };
};

и для начального время, когда он вызывает его с помощью

reducer(initialState, {type: "@@redux/INIT"});

, так что начальное состояние каждого редуктора заполняется

P.S. Если вы не передаете initialState в createStore, каждый редуктор принимает аргумент по умолчанию, передаваемый в например, const reducer =(state=initialState, action)=> и возвращает состояние для условия переключения по умолчанию, в результате чего initialState из каждого редуктора будет использоваться

0 голосов
/ 02 мая 2020

Вариант использования для передачи начального состояния в качестве второго аргумента в createStore предназначен для случаев использования, когда вы получаете это начальное состояние извне при загрузке приложения. Примерами могут быть состояние, генерируемое на сервере для приложений, отображаемых на стороне сервера, которые гидратируются на клиенте, или приложение, восстанавливающее локальное хранилище с избыточным состоянием при загрузке.

Начальное значение одного редуктора должно Если функция редуктора вызывается с неопределенным состоянием, проще всего использовать аргумент по умолчанию для состояния:

const reducer = (state = initialState, action) => ...

Это позволяет вам определить initialState рядом с местом, где определен редуктор, и он отлично масштабируется с combineReducers, когда у вас есть большее количество редукторов. Если вы поместите все initialState всех редукторов в один объект, который передается в createStore, становится трудно поддерживать синхронизацию c.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...