0
votes

I'm using React to pass a function from a parent component to a child component and trying to run it in the useEffect() hook.

Parent

function Parent(props) {

  function alertMe() {
    alert('me');
  }

  render (
    <div>
      <Child alertMe={alertMe} />
    </div>
  );
}

Child

function Child(props) {

  const { alertMe } = props;

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

  render (
    <div>
      // stuff
    </div>
  );
}

If I remove alertMe as a dependency in the useEffect() of the Child component, it only fires once, but I get a warning:

React Hook useEffect has missing dependencies: 'alertMe'. Either include it or remove the dependency array react-hooks/exhaustive-deps

The alertMe function is defined once in the Parent component on load, so I don't understand why it would run endlessly in the Child component. It's not changing like state.

How can I add alertMe as a useEffect() dependency but still only run it once?

1
remove it from the second argument array of useEffect. If you give useEffect an empty array as the second argument it will only run on mount. - skellertor
@skellertor Yes, but then I get the warning. - Michael Lynch

1 Answers

0
votes

See, your Parent re-declares alertMe each time it's re-rendered. And since alertMe is referentially different useEffect in Child will detect that and re-run.

Better not fighting with useEffect's dependencies(they are for a reason!). Let's ensure your alertMe is referentially the same:

function Parent(props) {

  const alertMe = useCallback(() => {
    alert('me');
  });

  render (
    <div>
      <Child alertMe={alertMe} />
    </div>
  );
}

Think about useEffect with dependencies list as about componentDidUpdate in hooks' world. Better keep component in sync with props than ignore changes outside.