Photo by Lautaro Andreani on Unsplash

Right Way To Render Components In React

Getting The Basics Right In ReactJs

The coding mistake I am going to cover in this blog post is majorly a result of the experiences I had with React over these years as a frontend developer. This is a tricky one that at first you’ll feel there is nothing wrong/broken — until it does!

Wrongly Calling The Functional Components

There are two ways in which you can call functional components in React. Consider a functional component Sample 

import React from 'react';
import './style.css';

const Sample = () => {
return (
<>
<h1>This is a sample component</h1>
</>
);
};
export default function App() {
return (
<div>
{/* Method 1 */}
<Sample />

{/* Method 2 */}
{Sample()}
</div>
);
}

Take this code and play it here. You’ll notice that both pieces work just fine. And that is how you make mistake number 1. They “appear” to be working fine but if you understand the inner workings of React, you’ll spot the difference.

The issue with Method 2 i.e {Sample()} calling the functional component like this is it “merges” the two components — App and Sample into one. 

Made some changes to the Sample component.

const Sample = () => {
const [value, setValue] = useState(false);
return (
<>
<button type="button" onClick={() => setValue(state => !state)}>Toggle Value</button>
<h1>This is a sample component {value.toString()}</h1>
</>
);
};
export default function App() {
return (
<div>
{/* Method 1 */}
<Sample />
</div>
);
}

When the button “Toggle Value” is clicked, the state change takes place and ONLY the functional component Sample re-renders. This is because the way we are using this component in the main App component. Here, the Sample and App component are not merged and are mutually exclusive as seen in the React Dev Tools “Components” tab.

Sample and App components using Method 1of rendering functional component
Sample and App components using Method 1of rendering functional component

This is also the “correct” way to use the component.

Now, if we change the way the Sample component is being rendered via Method 2, we’ll notice that the re-render is not scoped to Sample component anymore. Because the App and the Sample component are merged, the entire App component re-renders.

const Sample = () => {
const [value, setValue] = useState(false);
return (
<>
<button type="button" onClick={() => setValue(state => !state)}>Toggle Value</button>
<h1>This is a sample component {value.toString()}</h1>
</>
);
};
export default function App() {
return (
<div>
{/* Method 2 */}
{Sample()}
</div>
);
}

You can see the “merge” by using the React Developer Tools Chrome extension. If you inspect the app and check out the Components tab, you’ll only see App as a rendered component but you’ll still be able to see the contents of Sample component.

Merged Sample and App components using Method 2 of rendering functional component
Merged Sample and App components using Method 2 of rendering functional component

Hence, render the functional components properly using Method 1 i.e. <Sample/> and not Method 2 {Sample()}.The second method actually makes the functional component a “custom hook”.

As a proof of this, you’ll also encounter this error on the console when you conditionally render the Sample component using Method 2.

function App() {
const [value, setValue] = useState(false)
const clickHandler = (e) => {
setValue(e.target.value)
}
return (
<div className="App">
{/* <Sample/> */}
<input type='checkbox' onChange={clickHandler}/>
{value && Sample()}
</div>
)
}

The above piece of code will generate the error below because now the Sample component is being treated as a custom hook which we are trying to call “conditionally”. This violates the very rule of using hooks.

React Error
React Error

There are other mistakes I made and learnt from over the years while working as a Frontend Developer that you can read about it here — What Not To Do In ReactJS


Thanks for reading ❤

If this blog was able to bring value, please follow me on Medium! Your support keeps me driven!

If you enjoy reading stories like these and want to support me as a writer, consider signing up to become a Medium member. It’s $5 a month, giving you unlimited access to stories on Medium. If you sign up using my link, I’ll earn a small commission.

Want to connect?
Follow me on
Twitter and LinkedIn or reach out in the comments below!

My name is Aditya. I am a Senior Software Engineer. I blog about web development.

Leave a Reply

Your email address will not be published. Required fields are marked *