0

While app rendering, child Component useEffect triggered earlier than parents Layer useEffect . Why it happens and how to fix this issue? Please advice

Layer:

const Layer = (p) => {
     useEffect(() => {
         console.log(token, "Layer token");
     }, []);
    return (
        <>
            {p.children}
        </>
    )
}
export default Layer;

Component:

const Component = () => {
     useEffect(() => {
         console.log(token, "Component token");
     }, []);
    return (
        <></>
    )
}
export default Component;

Usage:

<Layer>
 <Component/>
</Layer>
cchEditor
  • 71
  • 1
  • 9
  • 1
    I think that it how it is supposed to happen. `useEffect` with empty arguments ([]) is another name for `componentDidMount`, so the parent will only be mounted when the child is mounted. See this [answer](https://stackoverflow.com/a/58353012/11023871) – David Buzatu Jan 11 '21 at 09:25
  • This might be a duplicate question. Please look at the answer in this topic https://stackoverflow.com/questions/58352375/what-is-the-correct-order-of-execution-of-useeffect-in-react-parent-and-child-co – Mantas Astra Jan 11 '21 at 09:26
  • Why? The children mounted first. Since there is no issue - what you want to fix? To have the layer's log show first? Pass a condition. – Dennis Vash Jan 11 '21 at 09:29
  • @DennisVash Expecting that Layer useEffect triggered before Component. – cchEditor Jan 11 '21 at 09:34
  • @DavidBuzatu Actually in a real application I have dependencies for both useEffects. I use the same value from useSelector from redux as dependence. in both useEffects – cchEditor Jan 11 '21 at 09:37
  • Pass a condition from Layer to Component if you want Layer to call first. Or use conditional rendering – Dennis Vash Jan 11 '21 at 09:46

1 Answers1

1

You can just have a render condition in Layer component:

const Layer = (p) => {
  const [isCalled, setIsCalled] = React.useState(false);
  React.useEffect(() => {
    if (!isCalled) {
      console.log("A");
      setIsCalled(true);
    }
  }, [isCalled]);
  return <>{isCalled && p.children}</>;
};

const Component = () => {
  React.useEffect(() => {
    console.log("B");
  }, []);
  return <></>;
};

Will log: "A", "B".

https://codesandbox.io/s/render-condition-call-80rc8

Dennis Vash
  • 50,196
  • 9
  • 100
  • 118