React Hooks are awesome once you understand how they work, and more importantly, why they work. They are the new hotness replacing the old approach to managing state and replacing the need for state machines like Redux. Aside from the frequent quirk you may run into, it’s an outstanding pattern and I recommend you read up on them. Full disclosure, my project was a React Native app.
The biggest hair pulling issue I ran into was when I was trying to populate a child component with the content of a form. Yeah, every tutorial out there takes this approach, but what set this one apart was that I was using a class object within my state versus just a regular string or other simple types as well as having default values within my Preview
component. When I listened within the useEffect()
for the form change, I could see that my setItem
function was getting called, and the state was updating. What was not happening was the child component was never updating with the new values.
This is what my component looked like when I kept running into this issue:
My Item
class and Preview
component is simplified to something like:
What do you notice about the Example
component? There is a call to Preview
and everything should just work right? Wrong!
Everyone says that React Hooks will only render when they detect a change in the state. When I added some debug logging to the useEffect()
, I was able to confirm that state was changing, and items
displayed it’s new value, but Preview
never re-rendered.
For me, it came down to two things. Javascript passing by value by reference (lol), and the component key
parameter. When item
had it’s default value set, it’s seen as an Item
-object. When the values updated, the object technically stayed the same, because the values in the class constructor were updated as well.
The second gotcha had it’s code cracked after scratching my eyes out reading this StackOverflow post, React: why child component doesn't update when prop changes. What I observed in the thread was that the key
parameter needed to also reflect the changed value to result in a re-render. This was imperative since the component still saw the same object within the prop because the values were being passed by reference and appeared the same, even though it changed.
I ended up creating an Item
class method named toKey()
that would return a string of the unique values from the class variables. This will always be unique and satisfy the React requirement. Secondly, when the props updated for the class, it would make sure that the class updated as well.
Here is the updated component with the changes implemented:
My hair turned grey while I debugged this, but I’m glad I spun my wheels. Coming from languages like Go, Rust and Python, I definitely learned a lot more within the React eco-system, and how to better control the state.
Member discussion