Как смотреть только одно поле в объекте в ловушке useEffect? - PullRequest
1 голос
/ 30 июня 2019
export const LocaleProvider = ({ children }) => {
  const [state, dispatch] = useReducer(reducer, { locale: DEFAULT_LOCALE });

  useEffect(() => {
    const storedLocale = getStoredLocale();
    if (storedLocale) dispatch(changeLocale(storedLocale));
  }, []);

  useEffect(() => {
    const { locale: currentLocale } = state;
    saveLocale(currentLocale);
  }, [state, state.locale]);

  return (
    <LocaleContext.Provider value={[state, dispatch]}>
      {children}
    </LocaleContext.Provider>
  );
};

Как смотреть только одно поле в объекте, состояние. Как вы можете видеть во втором эффекте, когда я смотрю только [state.locale], мой код VS отображает предупреждение eslint (act-hook / исчерпывающее-deps), React Hook useEffect имеет отсутствующую зависимость: «состояние». Либо включите его, либо удалите массив зависимостей. Когда я сохраняю свой код, код VS добавляет состояние в массив зависимостей ([state, state.locale]).

Ответы [ 2 ]

2 голосов
/ 30 июня 2019

react-hook/exhaustive-deps недостаточно умен, чтобы признать, что нужны только некоторые свойства объекта, он фокусируется на списке зависимых переменных (используемых внутри useEffect), поэтому мы можем сотрудничать с правилом, извлекая переменная:

const { locale: currentLocale } = state;
useEffect(() => {
  saveLocale(currentLocale);
}, [currentLocale]);
0 голосов
/ 30 июня 2019

Предупреждение приходит, потому что вы используете переменную состояния внутри функции useEffect. Это предупреждение может появиться только в том случае, если вы напрямую не используете переменную состояния.

Один из способов сделать это, а также оптимизировать этот код - использовать useCallback/useMemo. Проверьте следующий код:

export const LocaleProvider = ({ children }) => {
  const [state, dispatch] = useReducer(reducer, { locale: DEFAULT_LOCALE });

  useEffect(() => {
    const storedLocale = getStoredLocale();
    if (storedLocale) dispatch(changeLocale(storedLocale));
  }, []);

  const getCurrentLocale = useCallback(() => state.locale, [state.locale])

  useEffect(() => {
    const currentLocale = getCurrentLocale();
    saveLocale(currentLocale);
  }, [getCurrentLocale]);

  return (
    <LocaleContext.Provider value={[state, dispatch]}>
      {children}
    </LocaleContext.Provider>
  );
};

С помощью приведенного выше кода вы можете ограничить зависимости, как вы хотели.

...