We all know that React uses a unidirectional data flow. Meaning that data flows from parents to children only (via props), and children trigger events passed to them by parents. And that's a good thing actually. It keeps things clean, decoupled, and easily debuggable.
But in some rare cases, you might need to trigger a function at the child from the parent, without changing some state at the parent and re-rendering the tree. So can you do that?? . . Actually, yes. You can do this with a hook that you may have not seen before called useImperativeHandle. The way to use it is simple: 1- You create a ref at the parent & pass it to the child 2- The child receives the ref using forwardRef() 3- In the child, you use useImperativeHanlde to expose some functions at the child, for example focus(), and provide the implementation you want. 4- Now you are able to call this child exposed function directly from the parent by calling childRef.current.focus()
Handy, right? 😃
With that being said, please don't go starting to use it everywhere. That's because this hook can be considered an escape hatch that allows you to do something out of the usual react flow imperatively (hence the name). & that's something that you rarely will really HAVE to do. (In my past 4 years of working with React, I only used it a couple of times)
An example for a good use case is the following: You have a parent component that represents a particles container, and it has many children components that each represent a particle. When some event happens, you want to make the children particles move/behave in some way. So the standard way that you can implement this is to put some state in the parent, update it when the event happens, pass it to the children and make them update accordingly. And there is a high chance that this will give you the results you want with good enough performance. And if that's the case, then that's great. Keep it this way. Don't optimize pre-maturely.
But maybe you have a lot of child components, and the event that you want to respond to is being fired a dozens of time per second, like mousemove, scroll, animation...etc. So updating the state & re-rendering a lot of compoents many times per second might affect the smoothness of your app. So a possible solution for this case is to use useImperativeHandle in the child components and expose a method that directly changes the transform of the element. And problem solved!!
That's it for today folks. Leave a like if you learned something new 👍
And have a nice day.
About Me
I'm a freelance web developer who specializes in frontend.
I have a special love for React. And my personal goal is: Building things that are Awesome! ✨
If you are someone who is building a project where high quality is a MUST, then Let's Chat! I'll be glad to help you with it.