DEV Community

Discussion on: Simplify condition rendering in React.js

Collapse
 
baronw profile image
Baron Willeford

Your approach has an issue: the children are still being rendered, they’re just not being displayed. So if you have a component that, say, makes a network request when it mounts, that’s still going to happen, which is likely not what you want.

Collapse
 
florianrappl profile image
Florian Rappl

This is wrong. It's true that the elements are still constructed, but nothing is mounted and since React only goes in top-bottom the non-rendering / non-mounted children will never be looked at.

Look at this example.

   const IF = ({ condition, children }) => {
     if (!condition) return null;
     return <React.Fragment>{children}</React.Fragment>;
   };

   const Example = ({name}) => {
    console.log('Render Example', name);
    return <div />;
   };

ReactDOM.render(<div><IF condition={false}><Example name="false - not displayed" /></IF><IF condition={true}><Example name="true - displayed" /></IF></div>, document.querySelector("#app"))
Enter fullscreen mode Exit fullscreen mode

What you'll see in the console is:

"Render Example", "true - displayed"
Enter fullscreen mode Exit fullscreen mode

(Note there is no false - displayed shown.)

So there shouldn't be any such thing as a network request (which anyway shouldn't appear there, because these things are side-effects and, e.g., useEffect would only be called on mounted components anyway).

The only issue with this approach is that you construct more objects (i.e., React elements) than you would otherwise. This becomes only an issue when you have a larger render tree spawning from there.

Collapse
 
rmurati profile image
Redžep Murati

Exactly 🙂 Thank you for detailed clarification.

Thread Thread
 
trusktr profile image
Joe Pea

No issue with extra elements in Solid, no matter how big the app gets. Check it out!

solidjs.com

Collapse
 
hedwardd profile image
Heath Daniel

Interesting. Can you explain further? They are rendered by the parent component but the 'IF' component just controls whether they are displayed or not?

Collapse
 
baronw profile image
Baron Willeford

Correct. ‘IF’ and the child are rendered from the same place. The ‘children’ prop is just a reference, is not actual call site. To actually prevent it from being rendered, you would want to call the conditionally rendered component from the ‘IF’.

Thread Thread
 
hedwardd profile image
Heath Daniel

I'm not sure if this is a good way to test but I tried testing it by creating a component that logs to the console when it renders and it looks like that code never ran.

Link to CodePen: codepen.io/hedwardd/pen/xxdOpxy?ed...

Could it have something to do with it being a functional component?

Thread Thread
 
lfbergee profile image
Leiv Fredrik Berge

Exactly, this will actually add the child node to the tree and perform any effects for example. You can avoid this by using render props, but that kinda defeats the purpose.

Thread Thread
 
hedwardd profile image
Heath Daniel

Does it? Now I'm confused. If you look at the CodePen I created, the effects don't seem to run (unless I'm misunderstanding something)

Thread Thread
 
rmurati profile image
Redžep Murati

Actually it shouldn't run. I've created a codesadbox for you guys to check out where you can see both functional and class based components.
Here is the link:
codesandbox.io/s/nice-wiles-cwfi6?...