Выполнение кода непосредственно в компоненте функции реагирования, когда несколько состояний вызывают многократные повторные рендеринг - PullRequest
0 голосов
/ 28 мая 2019

У меня есть компонент, который использует и useState(), и другие пользовательские хуки несколько раз.

Я хочу действовать на основе этих значений состояния.Я мог бы сделать это непосредственно в теле компонента функции:

const MyComponent = () => {
  const [someState, setSomeState] = useState(false);
  const [otherState, setOtherState] = useState(false);
  const customHookValue = useCustomHook();

  if (someState) foo();
  const foo = () => setOtherState(!otherState);

  if (customHookValue > 10) bar();
  const bar = () => setSomeState(somestate > customHookValue);
}

Однако, каждый раз, когда someState изменяется (и происходит повторный рендеринг), также запускается второе условное выражение, вызывая запуск bar(), еслиусловные пропуски.Это кажется неестественным.Логически, bar() должен выполняться только при изменении customHookValue, поскольку someState изменяется только при изменении customHookValue с момента последнего рендеринга.

В итоге, повторный рендеринг вызван изменением someState не должен приводить к повторному запуску нескольких несвязанных функций установки состояний.Даже если их повторное выполнение не приводит к изменению результата программы, это логически неправильно.Они должны быть перезапущены только при изменении их соответствующих условий.Это может повлиять на производительность.

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

Вопросы

  1. Как бы я решить выше врекомендуемый способ?
  2. Должен ли я обернуть все условные выражения в useEffect или useMemo?

РЕДАКТИРОВАТЬ:

Обновлено второе условие, чтобы сделать мой вопрос более понятным (это должно зависеть от customHook).


УТОЧНЕНИЕ:

Поскольку оно может не иметьбыло ясно, моя проблема заключается в следующем.Когда состояние изменяется, происходит повторная визуализация.Это вызывает перезапуск всех функций в теле компонента.Теперь, если у нас много useState в компоненте, и только одно изменяется, будет запускаться куча потенциально не связанных с изменением состояния и потенциально дорогих функций, которые я определил в теле компонента.Эти функции изменения состояния должны были бы выполняться только в том случае, если изменились значения состояния, которые они пытаются установить.Если значения, которые они устанавливают, не изменились, им нет необходимости запускать снова.Но повторный рендеринг перезапускает все функции в теле компонента независимо.

1 Ответ

1 голос
/ 28 мая 2019

Похоже (как и другие) вы хотите useEffect:

useEffect(() => {
  if (someState) {
    setOtherState(!otherState)
  }
}, [someState, otherState])
useEffect(() => {
  if (customHookValue > 10) {
    setSomeState(someState > customHookValue)
  }
}, [customHookValue])

Поскольку вы хотите, чтобы setSomeState запускался только при изменении customHookValue, сделайте его единственным элементом в массиве зависимостей, переданном в useEffect.

exhaustive-deps eslint-plugin-Reaction-hooks будет жаловаться на второй useEffect, поскольку функция зависит от значения someState, даже если someState потенциально изменится только если customHookValue изменений. Я также не буду беспокоиться о вещах, которые могут повлиять на производительность, пока они не сделают. Я не знаю много о внутренностях React, но он делает некоторые вещи под капотом, чтобы избежать повторных рендеров, в которых он не нуждается, и может сделать несколько рендеров до того, как будет нарисовано реальное обновление.

...