简体   繁体   中英

Eslint React Hooks Error: eslint-plugin-react-hooks exhaustive deps warning for a function dependency in useEffect

 import React from 'react'; import PropTypes from 'prop-types'; import { connect } from 'react-redux'; import Actions from '../actions'; export const UserComponent = ({ foo, baz, bar, user, fetchUser }) => { useEffect(() => { console.log('##### I WAS CALLED I WAS CALLED'); fetchUser(); }, []); return ( <div> <p>{user.name}</p> <p>{foo} {baz} {bar}</p> </div> ); }; UserComponent.propTypes = { fetchUser: PropTypes.func.isRequired, user: PropTypes.shape({}), }; const mapActionsToProps = { fetchUser: Actions.fetchUser, }; const mapStateToProps = ({ data }) => ({ user: data.user, }); export default connect(mapStateToProps, mapActionsToProps)(UserComponent); 

I get an error 'React Hook useEffect has a missing dependency`

But If I put fetchUser in the dependency array

  useEffect(() => { console.log('##### I WAS CALLED I WAS CALLED'); fetchUser(); }, [fetchUser]); 

It causes an infinite loop.

I was using redux the wrong way in hook based components. This guide helped me a lot to use redux in functional components using hooks. https://react-redux.js.org/next/api/hooks

The problem is that the function fetchUser changes in each render. You can solve the problem using "useCallback".

Example:

const initFetchMethod = useCallback(() => {
   return dispatch(fetchUserAction())
}, [dispatch])


useEffect(() => {
   initFetchMethod();
}, [initFetchMethod]);

References:

Disable the es-lint warning if fetchUser action does not change in app lifecycle

Since fetchUser is an redux action and it is not going to change in your app lifecycle, i would say you can safely disable the rule for your case.

useEffect(() => {
    console.log('##### I WAS CALLED I WAS CALLED');
    fetchUser();
    //eslint-disable-next-line import/no-extraneous-dependencies
  }, []);

The error says, you need to put all resources(vars/functions) used by the effect callback inside the dependencies array.

So, you need to put fetchUsers in the dependencies array. But, it will cause infinite loop. Because, fetchUsers instance is recreated everytime.

You need to maintain a loading state for the api response. And, put a check in the callback like below:

useEffect(() => {
    if(!user && !loading ) {
        fetchUser();
    }
}, [fetchUser, user]);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM