Forcing state reset on a React component by using the key prop

Alberto Gasparin
3 min readDec 5, 2017

Did you know that you can use the key prop to force reset a component state? Most of the times you want to prevent that, but sometimes it is particularly helpful and helps keeping your code clean.

What is the key prop?

React key prop is a special prop that can be added to any component in order to explicitly tell React its identity. The common scenario where a component requires a key prop is within a list: React needs it in order to understand which items have been added, removed or, more generically, modified. This allows for advance DOM manipulations, preventing nodes from being destroyed and recreated for no reason. The key prop also prevents list items from loosing state between renders.

Key prop works even on non-list components

What it might sounds as a surprise, however, is that the key prop can be used on any component regardless and if used correctly can solve unwanted state persistency in a really clean way.

For instance, let’s assume that you are building a chat app with a list of rooms on the left and the active room on the right together with a textarea where the user can write a message:

class App extends React.Component {
state = {
activeChat: null,
};
render() {
return (
<div>
<ChatList
onClick={chat => this.setState({ activeChat: chat })}
/>
<Chat
activeChat={this.state.activeChat}
/>
</div>
);
}
}
class ChatList extends React.Component {
// ... implementation
}
class Chat extends React.Component {
state = {
message: ''
};
render() {
if(!this.props.activeChat) return null;
return (
<div>
{this.props.activeChat.messages.map(m => (
/* render messages */
)}
<textarea value={this.state.message} />
</div>
);
}
}

Whenever the user clicks on a ChatList item, the App activeChat state attribute changes. Based on the current implementation however, when that happens the message is persisted instead of being reset.

One solution is to define componentWillReceiveProps, check if activeChat prop has changed and if so reset the message field manually. This solution works fine, however requires you to be the owner of the component. If Chat is a component written by someone else with its own state, you might have hard times trying to reset it.

Discarding current component instance

Enters the key prop: as we said earlier, it helps React identifying a component but it also can be used to tell React that the component identity has changed, forcing a full re-instantiation of that component. Tweaking the example above:

// ...
<Chat
key={this.state.activeChat && this.state.activeChat.id}
activeChat={this.state.activeChat}
/>

Now the state of the Chat component is bound to activeChat.id. On activeChat change, React will discard the current Chat instance and create a new one with a fresh state.

Be aware of the performance implications

While this is a nice trick that might reduce the complexity of your app, it is important to remember that this approach makes React discard the entire component instance and DOM tree. In the above example, most of the Chat component will be redrawn anyway on activeChat change, so it might be a good enough solution. On real word applications, you should limit non-list components with keys and avoid setting it on top level ones, as it might be the cause of (hard to spot) performance issues.

--

--

Alberto Gasparin

Being a Frontend Developer is learning something new every day