Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

React listed objects unmount on state change

I have two components in my react (ts) app.

App.tsx:

import { useState } from 'react'
import Number from './Number'
import './App.css'

function App() {
    const [list, setList] = useState(["1", "2", "3", "4"]);
    const [x, setX] = useState({});

    function ComponentList(){
        return(<>
            {list.map(i => <Number num={i} key={i}/>) }
        </>)
    }

    return (
        <div className="App">
            <ComponentList/>
            <div onClick={()=>{
                setX({});
            }}>Update</div>
        </div>
    )
}

export default App

Number.tsx:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

import React, {useState} from 'react'

type props = {
    num: string
}

function Number({num}:props) {
    const [color, setColor] = useState("rgb(0, 0, 0)");

    return (
        <div style={{color: color}} onClick={()=>{
            setColor("rgb(255, 255, 255)");
        }}>
            {num}
        </div>
    )
}

export default Number

Here’s the problem:
When any state on the parent component (App.tsx) changes, the Number components in the list re-mount, resetting all their states to initial value. How can I get rid of this problem while keeping the list component?

The issue is very simple to re-create. When you use these two components in a react app and click the numbers to change their color, the color is reset upon clicking the "update" button, which seems illogical to me since the "setX" call doesn’t change anything about the list.

>Solution :

function App() {
    // ...

    function ComponentList(){
        // ...
    }
}

You’ve defined ComponentList inside of App. This isn’t supported. Every time App rerenders, you create a brand new definition for ComponentList. Its code may have the same text as the previous one, but it’s a different function, so a different component type as far as react is concerned. So react has to unmount the old ones and mount the new ones.

The fix is to move the component out. You’ll need to change list to be a prop instead of a closure variable

function App() {
  const [list, setList] = useState(["1", "2", "3", "4"]);
  // ...
  <ComponentList list={list}/>
  // ...
}

function ComponentList({ list }){
  return(<>
    {list.map(i => <Number num={i} key={i}/>) }
  </>)
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading