简体   繁体   中英

React Hook useCallback has a missing dependency. Either include it or remove the dependency array react-hooks/exhaustive-deps

I used useEffect in my component in order to execute an async function.

 useEffect(() => {
    scoreRequest(answers);
  }, [answers]);

Then I get this warning:

React Hook useCallback has a missing dependency: 'scoreRequest'. Either include it or remove the dependency array  react-hooks/exhaustive-deps

I used the useCallback to avoid this warning:

const getScore = useCallback(() => {
  scoreRequest(answers);
  }, [answers]);

  useEffect(() => {
    scoreRequest(answers);
  }, [answers]);

But still got the same error. However, I found a similar question and it's mentioned in the answer either to declare the function into the useEffect or I could disable the rule. The function scoreRequest() declared in another file and I don't want to mix it with my component.

export const scoreRequest = (answers: IAnswer[]): ThunkAction<void, AppState, null, Action<string>> => {
  return async (dispatch: Dispatch) => {
    dispatch(startScoreRequest());
    getScoreApi(answers).then((response: AxiosResponse) => {
      const { data } = response;
      const answer = {
        scoreLabel: data.message,
        userScore: data.result.userScore,
        totalScore: data.result.totalScore,
        emoji: data.result.emoji,
        scoreLabelColor: data.result.scoreLabelColor
      };
      dispatch(successScore(answer));
    }, (error: AxiosError) => {
      let errorMessage = "Internal Server Error";
      if (error.response) {
        errorMessage = error.response.data.error;
      }
      dispatch(failScore(errorMessage));
      dispatch(errorAlert(errorMessage));
    });
  };
};

Is it any solution to fix this warning?

When receving functions as props you should explicitly declare it inside your dependency array, the problem is functions change every render. For what I can see from your code scoreRequest is an action creator. You could import it outside your component and dispatch it like this

import { actionCreator } from './actions'
import { useDispatch } from 'react-redux'

const Component = () =>{
    const dispatch = useDispatch()

    useEffect(() =>{
        dispatch(actionCreator(answers))
    },[dispatch, answers])
}

This will avoid es-lint warning, cause your action creator it's imported outside your component, and dispatch it's memoized so it won't change every render. React-redux even mentioned that if you need to pass an action creator via props you should memoize it first

When passing a callback using dispatch to a child component, it is recommended to memoize it with useCallback, since otherwise child components may render unnecessarily due to the changed reference.

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