11

I wanna fetch my categories whenever my component is mounted using react hooks useEffect and not on every re-render. But i keep on getting this warning React Hook useEffect has a missing dependency:'dispatch'.

Here's my code:

const categories = useSelector(state => state.category.categories);
const dispatch = useDispatch();

useEffect(() => {
    console.log('effecting');
    const fetchCategories = async () => {
       console.log('fetching');
       try {
            const response = await axios.get('/api/v1/categories');
            dispatch(initCategory(response.data.data.categories));
       } catch (e) {
           console.log(e);
       }
    }

    fetchCategories();
}, []);

3 Answers 3

22

You can safely add the dispatch function to the useEffect dependency array. If you look the react-redux documentation, specially the hooks section, they mention this "issue".

The dispatch function reference will be stable as long as the same store instance is being passed to the . Normally, that store instance never changes in an application.

However, the React hooks lint rules do not know that dispatch should be stable, and will warn that the dispatch variable should be added to dependency arrays for useEffect and useCallback. The simplest solution is to do just that:

export const Todos() = () => {
const dispatch = useDispatch();

useEffect(() => {
    dispatch(fetchTodos())
  // Safe to add dispatch to the dependencies array
  }, [dispatch])

}

Sign up to request clarification or add additional context in comments.

Comments

5

Add dispatch to your dependency array (which is currently empty).

useEffect(() => {
    console.log('effecting');
    const fetchCategories = async () => {
       console.log('fetching');
       try {
            const response = await axios.get('/api/v1/categories');
            dispatch(initCategory(response.data.data.categories));
       } catch (e) {
           console.log(e);
       }
    }

    fetchCategories();
}, [dispatch]);

6 Comments

That works, but how is that makes sense to add a function on my dependency array?
So useDispatch will return a reference to the dispatch function from the Redux store which can change so you should add it to your dependency array to ensure you're always referencing the correct function.
How a function from redux store would change? Isn't the state from redux changes and not the function from dispatch?
@boosted_duck I seriously have a same question. how that 'dispatch' reference could be changed? why do we have to put that in the dependency list? we don't have to do that when using useReducer.
I think it’s because React’s eslint only allows a few things to be used in an effect without being in the dependency array: useRef, setState, and dispatch from useReducer. Why? Because it knows these are core variables that will never be reassigned. You can get around this error by using useRef if you’d like. It’s annoying, but that’s the best solution for now.
|
0

It might be a problem with ignored promise.

fetchCategories() returns a promise.

You can try

useEffect(() => {
    const fetchCategories = async () => {
       try {
            const response = await axios.get('/api/v1/categories');
            await dispatch(initCategory(response.data.data.categories));
       } catch (e) {
           console.log(e);
       }
    }

    fetchCategories().then(res => (console.log(res());
}, []);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.