duacos
duacos

Reputation: 69

React: re-render even if there aren't changes in state

Ok so I know the componet is rerendered when the state changes, but what if I want to reset the state. Take a look the following example:

const Parent = ({ type }) => {
  switch (type) {
    case "number":
      return <ShowNumber />;
    case "text":
      return <ShowText />;
    default:
      return <h1>nothing to do here</h1>;
  }
};

const ShowNumber = () => {
  const [number, setNumber] = useState(0);

  return (
    <>
      <h1>{number}</h1>
      <button
        onClick={() => {
          setNumber(prevNumber => prevNumber + 1);
        }}
      >
        Update number from child
      </button>
    </>
  );
};

const ShowText = () => {
  return <h1>{"Hello world"}</h1>;
};

export default () => {
  const [type, setStype] = useState("");

  return (
    <>
      <Parent type={type} />

      <button
        onClick={() => {
          setStype("number");
        }}
      >
        Show number
      </button>

      <button
        onClick={() => {
          setStype("text");
        }}
      >
        Show text
      </button>
    </>
  );
};

if I update my number and click on "Show text", then the ShowText component is called. Naturally if I go back to the ShowNumber component, my number is back to cero.

But what if I want to reset the number (or any other state related stuff) without switching (eg, every time I press the button "Show number" make my number go back to cero)

Edit immutable-water-s0trb

Upvotes: 3

Views: 1620

Answers (4)

EvanMorrison
EvanMorrison

Reputation: 1217

As it is now, clicking on "Show Number" a second time will not even cause a rerender of parent because the state doesn't change. To do what you want, you will need some additional state in Parent, like a counter that changes on every click. Then you can set that as a key on ShowNumber and a change in the key will cause a reset of state. Here's the updated code.

const Parent = ({ type, count }) => {
  switch (type) {
    case "number":
      return <ShowNumber key={count} />;
    case "text":
      return <ShowText key={count} />;
    default:
      return <h1>nothing to do here</h1>;
  }
};

const ShowNumber = () => {
  const [number, setNumber] = useState(0);

  return (
    <>
      <h1>{number}</h1>
      <button
        onClick={() => {
          setNumber(prevNumber => prevNumber + 1);
        }}
      >
        Update number from child
      </button>
    </>
  );
};

const ShowText = () => {
  return <h1>{"Hello world"}</h1>;
};

export default () => {
  const [type, setStype] = useState("");
  const [count, setCount] = useState(0);

  return (
    <>
      <Parent type={type} count={count} />

      <button
        onClick={() => {
          setCount(count => count + 1);
          setStype("number");
        }}
      >
        Show number
      </button>

      <button
        onClick={() => {
          setCount(count => count + 1);
          setStype("text");
        }}
      >
        Show text
      </button>
    </>
  );
};

Edit sweet-darkness-r7e7v

Upvotes: 2

hgb123
hgb123

Reputation: 14891

You could achieve that, there are two things to do:

  • retriggering the state, by replacing setting value by setting object, so Parent component will also be rerender everytime you press the button
    const [state, setState] = useState({});
    ...
    setState({ type: "number" });
    
  • remounting expected component (i.e ShowNumber), by setting unique component key (reference answer for more detail)
    return <ShowNumber key={`show-number-${new Date().getTime()}`} />;
    

I forked and modified with new sandbox:

Edit modest-newton-etk9y

Upvotes: 2

Grant Singleton
Grant Singleton

Reputation: 1651

As mentioned in the comments you should just reset the state in a handler. Technically a re-render would not reset the state since a component re-renders each time state changes but that doesn't wipe it clean. What you are thinking about is unmounting and remounting the component which is happening when you refresh the page or navigate away and come back. The best solution for this is to set the state to the original values.

Upvotes: 1

Arnab
Arnab

Reputation: 961

In that case You have to reset your state to 0 .

You can do it by adding a function:

setNumber(0)

You can execute it when you click Show Text

Upvotes: 0

Related Questions