1

Given a top-level App component that renders the following heirarchy:

<Parent>
  <Child />
</Parent>

If both Parent and Child call the same hook to obtain some global state, and that state changes, will Parent or Child be re-rendered first?

Also, say they both use some variable, user, from global state, and that Parent only renders its children prop if user is not undefined. Will the Child prop ever be rendered with an undefined user?

Jordan Walker
  • 550
  • 1
  • 5
  • 17
  • 1
    For example if you rendering the child only when the user is present i infer that you mean something like this - { user && – Shyam Jun 03 '21 at 11:05
  • You can check it by adding a `console.log` in render function. – Dennis Vash Jun 03 '21 at 11:06
  • Does this answer your question? [In which order are parent-child components rendered?](https://stackoverflow.com/questions/44654982/in-which-order-are-parent-child-components-rendered) – pilchard Jun 03 '21 at 11:06
  • @Shyam Sort of. I mean in `Parent` I would have `{user && children}`. The `children` would in turn be `` in this case. I expected that `Child` should never even be rendered if `user` is `undefined`, but in my real production app it is, so I'm getting a `user undefined` error in `Child`. Note that both `Parent` and `Child` get `user` from a global hook -- it's not passed from `Parent` to `Child`. – Jordan Walker Jun 03 '21 at 11:17
  • @DennisVash I've tried that and I'm getting different logs locally and in production. Locally, `Parent` renders first, but in production, `Child` renders first, even though I'd expect it not to render at all, given the conditional I have in `Parent`. Local console logs: AuthLayout CustomerDetailsForm UPDATING USER VARIABLE USER VARIABLE UPDATED AuthLayout Production console logs: AuthLayout CustomerDetailsForm UPDATING USER VARIABLE USER VARIABLE UPDATED CustomerDetailsForm TypeError: user is undefined in CustomerDetailsForm – Jordan Walker Jun 03 '21 at 11:27

1 Answers1

0

Here is a snippet logging mount/unmount of parent and child. Child is only rendered when the state value is odd. Both components are accessing the same Context.

const { useState, createContext, useContext, useEffect, useRef } = React;

const ViewContext = createContext();
const ActionsContext = createContext();

function MyContainer() {
  const [contextState, setContextState] = useState(0);

  return (
    <ViewContext.Provider value={contextState}>
      <ActionsContext.Provider value={setContextState}>
        <Incrementor />
        <Parent />
      </ActionsContext.Provider>
    </ViewContext.Provider>
  )
}

function Incrementor() {
  const setContextState = useContext(ActionsContext);

  const increment = () => {
    console.clear();
    setContextState(p => p + 1);
  }

  return <button onClick={increment}>increment</button>;
}

function Parent() {
  const contextState = useContext(ViewContext);

  useEffect(() => {
    console.log(contextState, ' - Parent Mounted');
    return () => console.log(contextState, ' - Parent Unmounted');
  }, [contextState]);

  return (
    <div>
      <p>This is the parent: {contextState}</p>
      {contextState % 2
        ? <ConditionalChild />
        : null}
    </div>
  );
}

function ConditionalChild() {
  const contextState = useContext(ViewContext);

  useEffect(() => {
    console.log(contextState, ' -  Child Mounted');
    return () => console.log(contextState, ' -  Child Unmounted');
  }, [contextState]);

  return (
    <div>
      <p>This is the child: {contextState}</p>
    </div>
  );
}

ReactDOM.render(
  <MyContainer />,
  document.getElementById("root")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>

<div id="root"></div>
pilchard
  • 12,414
  • 5
  • 11
  • 23