5
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>
  );
};

How to watch only a single field in an object, state. As you can see in the second effect, when I watch only [state.locale] my VS code shows an eslint warning(react-hook/exhaustive-deps), React Hook useEffect has a missing dependency: 'state'. Either include it or remove the dependency array. When I save my code VS code adds state in the dependencies array ([state, state.locale]).

Henok Tesfaye
  • 8,287
  • 13
  • 47
  • 84

2 Answers2

4

The react-hook/exhaustive-deps is not smart enough to recognize that only some properties of an object are needed, it focuses on a list of dependee variables (those used inside the useEffect), so we can cooperate with the rule by extracting a variable:

const { locale: currentLocale } = state;
useEffect(() => {
  saveLocale(currentLocale);
}, [currentLocale]);
Aprillion
  • 21,510
  • 5
  • 55
  • 89
0

The warning comes because you're utilizing the state variable inside the useEffect function. This warning can only go if you don't directly utilize the state variable for anything.

One way to do this and also optimize this code further would be to use useCallback/useMemo. Check out the following code:

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>
  );
};

With the above code, you get to limit the dependencies as you wanted.