DEV Community

Kuldeep Bora
Kuldeep Bora

Posted on

React: Create component inside a component (?)

I recently observed one issue in my component rendering. Consider this code

const App = () => {
const [search, setSearch] = useState('');

const Users = ()=>  <UserList pattern={search}/>;

return (
    <div id="app" className="home-page">
      <Header />
      <WelcomeSlogan/>
      <Users/>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

Here, the 'Users' component is re-rendering whole list whenever the search string changes. This is because in functional component, whole function body gets execute again (except hooks part) whenever local state (search) changes. What we want is only unmatched items to be removed from list. So the simple fix is to not create a component inside functional component.
Using

<UserList pattern={search}/>

directly inside return will fix our issue.

return (
    <div id="app" className="home-page">
      <Header />
      <WelcomeSlogan/>
      <UserList pattern={search}/>
    </div>
  );
Enter fullscreen mode Exit fullscreen mode

So the take away - NEVER CREATE A COMPONENT INSIDE ANOTHER FUNCTION COMPONENT.

However, this is not true in case of react class components. Since only render() method gets executed when re-rendering, we can create other (functional) components inside a class component. Like below:

class App extends React.Component {
constructor(props) {
      super(props);
      this.state = {
          search: ''
      }
      ...
  }
getUserList() {...} // returns List based on this.state.search
getComponent() {...} //create component here. returns UI element(s)

render() {
  return(
   <div> 
     {getUserList() }
     <div> { getComponent() } </div>
   </div>)
}
Enter fullscreen mode Exit fullscreen mode

This however works well. The getUserList component does not re-render whole list when search changes. Which is desired behavior. This might be because:

  1. Functions are not part of class instance.
  2. Only render function gets called when component re-render.

Hence, I think, IT's OK TO CREATE FUNCTIONAL COMPONENTS INSIDE A CLASS COMPONENT(?).

This was a good lesson for me and I can say I understand JS and React a bit better than before. (Feel free to add/correct me in comment section)

Thanks All.

Top comments (8)

Collapse
 
ksi9302 profile image
Peter Sugin Kim

Me watching this after having made 10 functional components inside a functional component.

Collapse
 
artidataio profile image
Imaduddin Haetami

Hmm, while possible my experience is doing such a thing was buggy with images keep reflushing

Collapse
 
sharukhhope profile image
Sharukh babu

You can actually call your functional component within another functional component using {Users()} just like how you would in a class component.
It won't bother your renders as it is not being called as a react component.

Collapse
 
rsweetland profile image
Reilly Sweetland

Thanks to your comment, I found a case within a class component where caused a rerender, but {Users()} did not. Thanks for sharing.

Collapse
 
ekaterina_vu profile image
Ekaterina Vujasinović

Components should be reusable and composable. It would be better to define each component in a separate file and use export/import. Your code would be more flexible that way.

Collapse
 
borasvm profile image
Kuldeep Bora

Yes I agree. I was just playing and experimenting with code. :)

Collapse
 
ramesh7128 profile image
Ramesh

concise and clear.

Collapse
 
arman_khan_27d377421f8b99 profile image
Arman Khan

it is very noticeable if you use a text input component inside the nested component