Why is function not called when virtually-rendered only

Viewed 31

I am trying to understand when the function body of the Label function I have here will run.

export default function App() {
  const label = <Label>Foo</Label>;

  return <Button>{label}</Button>;
}

const Button = (props) => {
  const shouldRenderChildren = false;

  return <button>{shouldRenderChildren && props.children}</button>;
};

const Label = () => {
  console.log("runing Label function");
  return <span>label</span>;
};

I created a Codesandbox - https://codesandbox.io/s/why-is-label-method-not-called-zodvn4?file=/src/App.js

Notice how in the Label function there is a console.log. I virutally-render this component before the return statement in App. I was expecting this function would have been called. However trying that Codesandbox above, we see it is not called as there is no "runing Label function" seen in console.

If I change shouldRenderChildren to true in Button then we see that the "runing Label function" log to console, so we see Label is called. Here it was virtually-rendered and dom-rendered.

Does React.createElement not actually call the render method unless it gets dom-rendered?

1 Answers

Instead of "dom-rendered", the word you might looking for is mounted.

When it comes to functional components, the body of the function is the equivalent of the render method in class components; Therefore, the function does not run until the component is being rendered.

If we look at the component life-cycle diagram once again, we can see that a component is not rendered, until it is ready to start mounting.

enter image description here

Therefore, I believe that at the very most, this line

const label = <Label>Foo</Label>;

is just calling the constructor for the component. This is what the docs says about the constructor:

The constructor for a React component is called before it is mounted

If you want to test it, the convert your component to a class component, and add some console.log to the constructor, then see what happens when you do: const label = <Label>Foo</Label>;

EDIT

I tested it, and not even the constructor of the component is invoked when it is not mounted:

https://codesandbox.io/s/why-is-label-render-not-called-vt05we

Therefore, it might best to assume that until a component is about to be rendered, it is not even constructed!

Related