Home » Reactjs » How can I reset a react component including all transitively reachable state?

How can I reset a react component including all transitively reachable state?

Posted by: admin November 30, 2017 Leave a comment

Questions:

I occasionally have react components that are conceptually stateful which I want to reset. The ideal behavior would be equivalent to removing the old component and readding a new, pristine component.

React provides a method setState which allows setting the components own explicit state, but that excludes implicit state such as browser focus and form state, and it also excludes the state of its children. Catching all that indirect state can be a tricky task, and I’d prefer to solve it rigorously and completely rather that playing whack-a-mole with every new bit of surprising state.

Is there an API or pattern to do this?

Edit: I made a trivial example demonstrating the this.replaceState(this.getInitialState()) approach and contrasting it with the this.setState(this.getInitialState()) approach: https://jsfiddle.net/emn13/kdrzk6gh/replaceState is more robust.

Answers:

To ensure that the implicit browser state you mention and state of children is reset, you can add a key attribute to the root-level component returned by render; when it changes, that component will be thrown away and created from scratch.

render: function() {
    // ...
    return <div key={uniqueId}>
        {children}
    </div>;
}

There’s no shortcut to reset the individual component’s local state.

Questions:
Answers:

You should actually avoid replaceState and use setState instead.

The docs say that replaceState “may be removed entirely in a future version of React.” I think it will most definitely be removed because replaceState doesn’t really jive with the philosophy of React. It facilitates making a React component begin to feel kinda swiss knife-y.
This grates against the natural growth of a React component of becoming smaller, and more purpose-made.

In React, if you have to err on generalization or specialization: aim for specialization. As a corollary, the state tree for your component should have a certain parsimony (it’s fine to tastefully break this rule if you’re scaffolding out a brand-spanking new product though).

Anyway this is how you do it. Similar to Ben’s (accepted) answer above, but like this:

this.setState(this.getInitialState());

Also (like Ben also said) in order to reset the “browser state” you need to remove that DOM node. Harness the power of the vdom and use a new key prop for that component. The new render will replace that component wholesale.

Reference: https://facebook.github.io/react/docs/component-api.html#replacestate