useEffect. Find the parent component that defines it and wrap that definition in useCallback

Viewed 1150

So this is my code in my profile actions

import axios from 'axios';

import { GET_PROFILE, PROFILE_ERROR } from './types';

// Get current users profile
export const getCurrentProfile = () => async (dispatch) => {
    try {
        const res = await axios.get('/api/profile/me');

        dispatch({
            type: GET_PROFILE,
            payload: res.data,
        });

        dispatch(getCurrentProfile());
    } catch (err) {
        dispatch({
            type: PROFILE_ERROR,
            payload: {
                msg: err.response.statusText,
                status: err.response.status,
            },
        });
    }
};

and this is my dashboard

import React, { useEffect } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { getCurrentProfile } from '../../actions/profile';

const Dashboard = ({ getCurrentProfile, auth, profile }) => {
    useEffect(() => {
        getCurrentProfile();
    }, []);

    return <div>Dashboard</div>;
};

Dashboard.propTypes = {
    getCurrentProfile: PropTypes.func.isRequired,
    auth: PropTypes.object.isRequired,
    profile: PropTypes.object.isRequired,
};

const mapStateToProps = (state) => ({
    auth: state.auth,
    profile: state.profile,
});

export default connect(mapStateToProps, { getCurrentProfile })(Dashboard);

and I get this errror "React Hook useEffect has a missing dependency: 'getCurrentProfile'. Either include it or remove the dependency array. If 'getCurrentProfile' changes too often, find the parent component that defines it and wrap that definition in useCallback"

2 Answers

As the warning says, you can can include getCurrentProfile as a dependency to useEffect.

Also since the getCurrentProfile function is being passed as a dispatch function to props form connect, its reference doesn't change and hence you need not worry about change in its reference or using useCallback to memoize it

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

Note that in the getCurrentProfile function you must not dispatch itself without a condition

export const getCurrentProfile = () => async (dispatch) => {
    try {
        const res = await axios.get('/api/profile/me');

        dispatch({
            type: GET_PROFILE,
            payload: res.data,
        });

    } catch (err) {
        dispatch({
            type: PROFILE_ERROR,
            payload: {
                msg: err.response.statusText,
                status: err.response.status,
            },
        });
    }
};

I guess that is the error from eslint wiht react-hooks plugin. The error mean when you use a hooks which accept array as a dependencies the plugin recommend to add any variable, function..., which have chance to change each render, inside the hook function to be included in dependency array. So how to fix it?

  • You can include the getCurrentProfile in dependency array, but make sure you use useCallback to wrap getCurrentProfile if you define component or a custom hook.
  • You can disable the effect of eslint if you wish by
useEffect(() => {
    getCurrentProfile();
   // eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
Related