0

I am new to react and come from a background of functional component only.

In my react project,

When I conditionally rendering , ie from false to true, the data inside child component will be gone.

Then I wonder why is that.

Then I heard a concept called unmounting. It means, when my condition change from true to false, the component will get unmounting. And in unmounting, the state inside will gone.

But then, it doesn't add up. Q: Whenever we re-render any other components, just like the normal situation, we will also unmount component in order to do re-rendering. And our state value would not be gone.

Why this problem was happened especially on having conditional statement in react?

Edit:

My emphsis is not on how to avoid state loss. My question is that why data will be gone in conditional rendering. And why unmounts will cause such problem, but re rendering would not cause such ( both also involves unmounting)

Here is my code

In parent:

import React, { useEffect, useState } from "react";
import ReactDOM from "react-dom";
import Child1 from "./child";

import "./styles.css";

function Parent() {
  const [message, setMessage] = useState("initial text");
  const [showChild,setShowChild] = useState(true);
  useEffect(() => {
    console.log("useeffect in parent");
  });

  return (
    <div className="App">
      <button onClick={() => setShowChild(!showChild)}>show child</button>
      {showChild? 
      <Child1 />
      :
      null
      
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<Parent />, rootElement);

In child:

import React, { useEffect, useState } from "react";

function Child1() {
  useEffect(() => {
    console.log("useeffect in child");
    console.log("newMessage: " + newMessage);
  });
  const [newMessage, setNewMessage] = useState("");


  return (
    <div>
      <input onChange={(event) => setNewMessage(event.target.value)} />
    </div>
  );
}

export default Child1;

Add some picture to illurste what I mean by data lose in conidtional rendering

  1. enter

https://i.stack.imgur.com/UrIhT.png

click to not show it

https://i.stack.imgur.com/0OC87.png

click to show again

https://i.stack.imgur.com/4zlWk.png

Ae Leung
  • 300
  • 1
  • 12
  • Please illustrate the situation that's contradicting. – Enfield Li Aug 19 '22 at 21:54
  • My question is that why data will be gone in conditional rendering. And why unmounts will cause such problem, but re rendering would not cause such ( both also involves unmounting, right? – Ae Leung Aug 19 '22 at 21:58
  • I added some photo to illustrate it – Ae Leung Aug 19 '22 at 22:03
  • 1
    State is bound to it's component, and React uses a tree structure to keep track of it's components, ie. a component tree. If one of the component unmounts, React remove it from the tree and destroy it's state. It's a guaranteed process. See [docs](https://beta.reactjs.org/learn/preserving-and-resetting-state#state-is-tied-to-a-position-in-the-tree) – Enfield Li Aug 19 '22 at 22:06
  • When normal componments get re rendering, should it also get unmount first, then it get mounted back? and why would not such unmount cause state gone? – Ae Leung Aug 19 '22 at 22:14
  • Take a look at this section of the docs: [Same component at the same position preserves state](https://beta.reactjs.org/learn/preserving-and-resetting-state#same-component-at-the-same-position-preserves-state). Yes the component is blown away, when it rerenders, but React is smart enough to remember, it is the same component at the same position, so it will keep the previous state. – Enfield Li Aug 19 '22 at 22:17
  • Oh I see, does it also related to virtual dom ? – Ae Leung Aug 19 '22 at 22:18
  • I believe virual DOM is the place where React does it's diffing process, and eventually renders the element to the real DOM. See this [answer](https://stackoverflow.com/a/21965987/16648127). – Enfield Li Aug 19 '22 at 22:33
  • 1
    Hi. If I helped you understand the problem, I can write an answer to summerize it. – Enfield Li Aug 19 '22 at 23:00
  • It helps, I guess this answer answered the essence of the question. React looks at the existence of previous component, if it is absent, its state will be gone. So, unmounting is not the key why the data is gone. Coz in re-rendering, no matter there is a conditional rendering or not, re-rendered components would be unmounted. But, if it is absent in the new re rendering, state are gone. – Ae Leung Aug 20 '22 at 17:39
  • If you want, you may also point out your answer's difference to the answers from below answerers. Then I may give you a upvote/accepted on your answer – Ae Leung Aug 20 '22 at 17:46

2 Answers2

0

Try moving all state management to the parent component and leave the child component 'dumb'. You can pass the setMessage and any other state variables to the child as props.

Parent:

import React, { useEffect, useState } from "react";
import ReactDOM from "react-dom";
import Child1 from "./child";

import "./styles.css";

function Parent() {
  const [message, setMessage] = useState("initial text");
  const [showChild,setShowChild] = useState(true);
  useEffect(() => {
    console.log("useeffect in parent");
  });

  return (
    <div className="App">
      <button onClick={() => setShowChild(!showChild)}>show child</button>
      {showChild? 
      <Child1 setMessage={setMessage}/>
      :
      null
      
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<Parent />, rootElement);

Child:

import React from "react";

function Child1({setMessage}) {

  return (
    <div>
      <input onChange={(event) => setMessage(event.target.value)} />
    </div>
  );
}

export default Child1;
Jake Zeitz
  • 2,429
  • 3
  • 23
  • 43
  • Thanks for suggesting a way to avoid state loss. But actually I knew this way. But my question is that why data will be gone in coniditional rendering. And why unmount will cause such problem, but re rendering would not cause such. – Ae Leung Aug 19 '22 at 21:19
  • When the component unmounts any state information related to that component is gone. Re-rendering is when the component updates based on it's current state, it continues to work because the component has not yet been destroyed. Once it is destroyed it unmounts removing the state. Read into react life-cycle hooks to get a better understanding. – Jake Zeitz Aug 22 '22 at 00:47
0

The answer for your question is very simple, While unmounting you are removing the component itself from react-dom. The state, props and all the data's handled inside your component will be active only If the component is inside the react-dom. If the particular component is unmounted, all the states and props that was created and processed will also be removed from react-dom along with the component. And the fresh component, state and props will be mounted in the react-dom if you conditionally render the component again.

Sujith Sandeep
  • 1,185
  • 6
  • 20