score:251

Accepted answer

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.

score:0

Maybe you can use the method reset() of the form:

import { useRef } from 'react';

interface Props {
    data: string;
}

function Demo(props: Props) {
    const formRef = useRef<HTMLFormElement | null>(null);

    function resetHandler() {
        formRef.current?.reset();
    }

    return(
        <form ref={formRef}>
            <input defaultValue={props.data}/>
            <button onClick={resetHandler}>reset</button>
        </form>
    );
}

score:2

The approach where you add a key property to the element and control its value from the parent works correctly. Here is an example of how you use a component to reset itself.

The key is controlled in the parent element, but the function that updates the key is passed as a prop to the main element. That way, the button that resets a form can reside in the form component itself.

const InnerForm = (props) => {
  const { resetForm } = props;
  const [value, setValue] = useState('initialValue');

  return (
    <>
      Value: {value}
      <button onClick={() => { setValue('newValue'); }}>
        Change Value
      </button>
      <button onClick={resetForm}>
        Reset Form
      </button>
    </>
  );
};

export const App = (props) => {
  const [resetHeuristicKey, setResetHeuristicKey] = useState(false);
  const resetForm = () => setResetHeuristicKey(!resetHeuristicKey);
  return (
    <>
      <h1>Form</h1>
      <InnerForm key={resetHeuristicKey} resetForm={resetForm} />
    </>
  );
};

score:14

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

score:22

Adding a key attribute to the element that you need to reinitialize, will reload it every time the props or state associate to the element change.

key={new Date().getTime()}

Here is an example:

render() {
  const items = (this.props.resources) || [];
  const totalNumberOfItems = (this.props.resources.noOfItems) || 0;

  return (
    <div className="items-container">
      <PaginationContainer
        key={new Date().getTime()}
        totalNumberOfItems={totalNumberOfItems}
        items={items}
        onPageChange={this.onPageChange}
      />
    </div>
  );
}

Related Query

More Query from same tag