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>
);
}
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>
);
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>)
}
This however works well. The getUserList component does not re-render whole list when search changes. Which is desired behavior. This might be because:
- Functions are not part of class instance.
- 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)
Me watching this after having made 10 functional components inside a functional component.
Hmm, while possible my experience is doing such a thing was buggy with images keep reflushing
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.
Thanks to your comment, I found a case within a class component where caused a rerender, but {Users()} did not. Thanks for sharing.
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.
Yes I agree. I was just playing and experimenting with code. :)
concise and clear.
it is very noticeable if you use a text input component inside the nested component