Может кто-нибудь объяснить функцию createStore и как простая передача ей функции счетчика позволяет ей узнать о состоянии?

#javascript #reactjs #redux

#javascript #reactjs #redux

Вопрос:

Эта функция createStore использует функции reducer, но я действительно не понимаю, что происходит, откуда она знает, каково текущее состояние счетчика, когда мы выполняем store.getState(), из чего я знаю, что createStore () вернет объект функций, но я не понимаю, как они работают. Кроме того, зачем нам нужен массив Listeners Я знаю, что кто-то объяснил это, но я ищу более простой пример, я был бы признателен, если бы кто-нибудь объяснил, что будет иметь этот массив и почему мы отписываемся от этих слушателей в конце.

Я бы действительно оценил также, если бы кто-нибудь объяснил мне, как отлаживать этот код, я продолжаю получать пустые значения в Chrome Debugger.

Последний вопрос, как простая передача функции счетчика позволяет ей узнать о своем состоянии. Я не вижу никакого назначения, подобного state = state внутри самой функции reducer. Заранее большое вам спасибо.

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

const createStore = (reducer) => {
  let state;
  let listeners = [];

  const getState = () => state;

  const dispatch = (action) => {
    state = reducer(state, action);
    listeners.forEach(listener => listener());
  };

  const subscribe = (listener) => {
    listeners.push(listener);
    return () => {
      listeners = listeners.filter(l => l !== listener);
    };
  };

  dispatch({});

  return { getState, dispatch, subscribe };
};

const store = createStore(counter);

const render = () => {
  document.body.innerText = store.getState();
};

store.subscribe(render);
render();

document.addEventListener('click', () => {
  store.dispatch({ type: 'INCREMENT' });
});
  

Ответ №1:

Как он узнает, каково текущее состояние счетчика, когда мы это делаем store.getState() ?

Оно хранится в state переменной. Изначально это так undefined , и всякий раз, когда вы вызываете dispatch , она вызывает переданный редуктор и выводит новое состояние. Чтобы получить обычное состояние, оно делает:

  dispatch({});
  

который затем вызовет редуктор как:

  state = reducer(/*state: */ undefined, /*action: */ {}) /*0*/
  

это введет ветвь коммутатора по умолчанию и вернет 0, следовательно state , с этого момента равно 0. Если вы снова вызовете dispatch, например:

   dispatch({ type: "INCREMENT" });
  

Затем редуктор вызывается снова, но на этот раз вводится другой bracnh переключателя, состояние увеличивается:

  state = reducer(/*state:*/ 0, /*action:*/ { type: "INCREMENT" }) /*1*/
  

Кроме того, зачем нам нужен массив Listeners?

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

почему мы отказываемся от подписки на этих слушателей в конце?

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

как простая передача функции счетчика позволяет ей узнать о своем состоянии?

Это не так. Как показано выше, reducer ( counter в данном случае) вызывается с пустым действием, которое затем приведет к исходному состоянию.

Я бы действительно оценил, если бы кто-нибудь объяснил мне, как отлаживать этот код

Я бы разместил несколько точек останова, например, в первой строке count , dispatch render функции и обработчика onClick, затем перезагрузил страницу, чтобы увидеть, что она вызывается count изнутри dispatch , затем каждый раз, когда вы нажимаете на страницу, она будет проходить код, подобный этому onClick -> dispatch -> count -> render .

Комментарии:

1. Итак, функция createStore выполняется только один раз, а затем редуктор счетчика выполняет все остальное?

2. Я не уверен, прав ли я, поэтому, если мы вызываем createStore только один раз, но у нас всегда есть ссылка на состояние и переменные прослушиватели, которые были созданы внутри createStore. Если это то, что происходит, не могли бы вы, пожалуйста, сообщить мне, что это вызывается в Javascript, потому что я думал, что область состояния — это внутренняя область этой функции, и у нас больше не должно быть доступа к ним. Я уверен, что ошибаюсь. Но, пожалуйста, дайте мне знать, что вы думаете.

3. @jason Я предполагаю, что термин, который вы ищете, — это «закрытие»

4. Большое вам спасибо, для меня это имеет большой смысл. Что касается закрытия, я сталкивался с ними раньше, и в большинстве примеров используется функция setTimeout, поэтому я никогда по-настоящему не понимал их. Но теперь это имеет смысл.