Есть ли способ наложить требования на зависимости хуков? - PullRequest
0 голосов
/ 07 мая 2020

В настоящее время я проверяю, имеет ли зависимость хука input useEffect () по крайней мере определенную длину перед вызовом loadSearchData(), который является методом asyn c, который обращается к API. * Есть ли способ переместить проверку ввода в параметр зависимости input для useEffect ()? Вероятно, случай, когда мне нужно написать собственный хук.

1 Ответ

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

Есть ли способ переместить проверку ввода в параметр зависимости ввода для useEffect ()? Вероятно, случай, когда мне нужно написать собственный хук.

Я бы построил его таким образом:


function useEffect2(effect, deps, isValid = true) {
  const cleanup = React.useRef(null);

  useEffect(() => {
    if (isValid) {
      if (typeof cleanup.current === "function") {
      // schedule cancellation of previous request right after effect has been called
      // using the Promise construct here so I don't have to deal with a throwing cancellation function
        Promise.resolve().then(cleanup.current);
      }

      // in case effect() throws, 
      // don't want to call the old cancellation function twice
      cleanup.current = null;
      // get new cancel-function
      cleanup.current = effect();
    }
  }, deps);

  useEffect(() => () => {
    // deal with cancellation on unmount
    typeof cleanup.current === "function" && cleanup.current();
  }, []);
}

useEffect2(loadSearchData, [input], input.length >= MIN_CHAR_INPUT);

Я просто хочу уточнить отмену. Это даст нам доступ к текущему вызову useEffect () в стеке и позволит нам правильно обрабатывать вызов без каких-либо утечек памяти

From https://reactjs.org/docs/hooks-effect.html#recap

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

Очистка, вероятно, лучшее название. Я чаще всего использую его для «отмены» предыдущих ajax -запросов, если они все еще ожидают ответа / предотвращения их обновления состояния. Я переименовал переменную в коде.

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

  1. когда (и только если) мы вызываем функцию эффекта
  2. на componentWillUnmount

Вот что это ref для. Поскольку ссылка перезаписывается при каждом вызове effect, утечки памяти не должно быть.

...