1pct
1pct

Reputation: 65

call function from useEffect and other function

i have a child component which emits an action to the parent component with a event:

Child component:

export default function ChildComponent(props) {
  const classes = useStyles();
  const [value, setValue] = React.useState([0, 5]);

  const handleChange = (_, newValue) => {
    setValue(newValue);
    props.updateData(newValue)
  };

  return (
    <div className={classes.root}>
      <GrandSonComponent
        value={value}
        onChange={handleChange}
      />
    </div>
  );
}

Parent component:

export const ParentComponent = () => {
  const [loading, setLoading] = React.useState(true);
  const { appData, appDispatch } = React.useContext(Context);

  function fetchElements(val) {
    fetchData(val);
  }

  // eslint-disable-next-line react-hooks/exhaustive-deps
  useEffect(() => { return fetchData() }, []);

  async function fetchData(params) {
    const res = await axios.get('/url', { params });
    appDispatch({ type: "LOAD_ELEMENTS", elements: res.data });
  }

  return (
    <div>
      <ChildComponent updateData={fetchElements}  />
    <div>
     .
     .
     .
   )
};

i would like to know how to remove this line // eslint-disable-next-line react-hooks/exhaustive-deps

I need to add this line, because otherwise i see the eslint error:

React Hook useEffect has a missing dependency: 'fetchData'. Either include it or remove the 
dependency array.eslintreact-hooks/exhaustive-deps

i need to use fetchData(params) function for the first time page is rendered and when user change/click value of child component with no eslit warnings!

Thanks!

Upvotes: 3

Views: 10539

Answers (1)

Yousaf
Yousaf

Reputation: 29282

First of all, you don't need to return the result of calling fetchData() function inside the useEffect hook.

Now coming to your problem, reason why you get a warning is because missing the dependencies of the useEffect could lead to bugs due to closures. React recommends that you don't omit any dependencies of the useEffect hook, useCallback hook, etc.

This sometimes leads to infinite loop of state update and re-render but that can be prevented by either using useCallback hook or other ways that could prevent useEffect hook from executing after each re-render of the component.

In your case, you could fix the problem by following the steps mentioned below:

  1. Wrapping fetchData function in a useCallback hook

    const fetchData = useCallback(async (params) => {
       const res = await axios.get('/url', { params });
       appDispatch({ type: "LOAD_ELEMENTS", elements: res.data });
    }, []);
    
  2. Add fetchData in the dependency array of the useEffect hook

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

Upvotes: 7

Related Questions