Реагировать на ловушку useRender, вызываемую дважды, если после этого выполняется настройка и состояние - PullRequest
3 голосов
/ 04 мая 2020

Я не уверен, является ли это ожидаемым поведением, но если вы выйдете из отправки (https://reactjs.org/docs/hooks-reference.html#bailing -out-of-a-dispatch ) во время использования ловушки useReducer, действие произойдет дважды, если за ним следует рендер. Позвольте мне объяснить:

// bailing out to prevent re-rendering
const testReducer = (state, action) => {
  switch (action.type) {
    case "ADD":
      state.test += 1
      return state;
  }
};

const myComponent = () => {
  let [totalClicks, setClicks] = useState(0);
    const [state, setState] = useReducer(testReducer, {
      test: 0,
    });

  const clickHandler = () => {
    setState({type: 'ADD'});
    setClicks((totalClicks += 1));
  };

  return (
    <div>
      <button onClick={clickHandler}>+</button>
      <p>{totalClicks}</p>
      <p>test count: {state.test}</p>
    </div>
  );
}

Когда вы нажимаете кнопку, state.test увеличивается на 2, а totalClicks увеличивается на 1. Однако, если бы я изменил редуктор так, чтобы он не Если вы не поможете одному, как показано ниже, они оба увеличатся на 1.

// non-bailing reducer
const testReducer = (state, action) => {
  switch (action.type) {
    case "ADD":
      return {
        test: state.test + 1,
      };
  }
};

Почему это так? И это ожидаемое поведение или ошибка? пример песочницы: https://codesandbox.io/s/sad-robinson-dds63?file= / src / App. js


ОБНОВЛЕНИЕ: после выполнения некоторой отладки, похоже, что это происходит только тогда, когда обернутый React.StrictMode

Кто-нибудь знает, что вызывает это ???

1 Ответ

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

В соответствии с do c из StrictMode , реакция намеренно вызывает функцию редуктора дважды с одним и тем же действием, поэтому выявляете незамеченные потенциально вредные побочные эффекты, что и происходит в вашем случае.

Строгий режим не может автоматически определять побочные эффекты для вас, но он может помочь вам обнаружить их, сделав их немного более детерминированными c. Это делается путем намеренного двойного вызова следующих функций: […] Функции, переданные для использования useState, useMemo или useReducer

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