Overview
So I'm quite embarrassed writing this actually, because I like to think of myself as having a good grasp on React, however like nearly every other day I was humbled by a Jon Snow moment. I was recently stumped when asked why we need to use keys in React for our dynamically rendered content. I've come across this error in React so many times, usually simply passing the item's index as the key prop and forgetting about it. Now, most of the time your components will render just fine, but there are a few instances that could throw a wrench into your JSX or at that very least leave you like me, paying for not knowing an answer to a fairly simple question.
Whats the deal keys?
One of the reasons React can quickly make update changes to the view, is that it only updates the parts of the DOM that it needs to. For example, let's say we have a simple todo list, where users can simply add a new todo item.
const TODOS = ["get groceries", "fold laundry", "Feed Fido"];
const TodoList = props => {
return (
<ul className="Todo">
{ TODOS.map(todo => <li>todo</li>) }
</ul>
)
};
The quickest and easiest way for React to update our todo list is if we keep all of our current items in the same order and just append our new todo at the end of the list. React can easily match our original items and since none of those have changed, the only update React needs to make is to our newly created todo item.
However, if we add our new item to the top of our list React can no longer easily match against our original list and must update every item in the list. Now, a few items wont affect our application's performance all that much, but as our list grows these performance changes become very noticeable.
What if we want our users to be able move tasks in order of importance or even remove items once they're completed, how do we handle this and still optimize for performance? Well, as you may have guessed, this is the exact issue the key
prop attempts to solve.
const TODOS = ["get groceries", "fold laundry", "Feed Fido"];
let id = 1;
const TodoList = props => {
return (
<ul className="Todo">
{ TODOS.map(todo => <li key={id++}>todo</li>) }
</ul>
)
};
Assigning a unique key to each of our Todo items allow React to be able match our items against their key, so even if our users sort the list in by importance, recently created or some other pattern, React will know which ones it needs to create or update and which ones it can simply pass over.
Notice however, that I didn't use the item's index here. Upon writing this post, I came across another helpful tidbit; React defaults to using an items index ad the key when one isn't provided. Index is usually fine as long as the list order never changes, however if we reorder out list we can get some unexpected state errors. Check out the React docs on reconciliation to learn a bit more about this behavior.
Conclusion
There are actually quite a few helpful resources out there explaining this already, but I figured another resource never hurts. The biggest take away for me (hopefully for you too), is that I have some tendencies to simply fix whatever console error I get inside my code so that I can continue to crank out components and get my view. Overlooking these errors though could cause a slower rendering time or unexpected behavior in your application. Also, I need to leave my pride at the door, because the more I learn the more I realize how little I actually know.
I'd love to learn if you've had any similar experiences with overlooking some of these simpler concept of a framework, language or any other topic is the vast developer world of ours.
Top comments (0)