Home > Back-end >  React onClick update useState variable and render updated
React onClick update useState variable and render updated

Time:10-08

I know this question has been asked before, but the solutions were different from the way I structure/code my React app as shown below. How use one update/render based on the updated listData?

import React, { useState } from "react";

const PageName = () => {

  const [listData, setlistData] = useState([]);

  function add(){
    let newrow = {};
    listData.push(newrow);
    setlistData(listData);
  }

  return (
    <div>
      {listData.length}

      <button onClick={() => add()}>Add</button>

      {
        listData.map(function (row, i) {
          return (
            <p key={i}>row</p>
          );
        })
      }
    </div>
  );
};

export default PageName;

CodePudding user response:

If it is a state variable it is react's job to rerender. Your job is to ensure you are passing in a new reference to setState() without mutating the state.

Use ... spread operator.

import React, { useState } from "react";

const PageName = () => {

  const [listData, setlistData] = useState([]);

  function add(){
    let newrow = {};
    let newListData = [...listData];
     newListData.push(newrow);
    setlistData(newListData);
  }

  return (
    <div>
      {listData.length}

      <button onClick={() => add()}>Add</button>

      {
        listData.map(function (row, i) {
          return (
            <p key={i}>row</p>
          );
        })
      }
    </div>
  );
};

export default PageName;

CodePudding user response:

The reference stays the same if you only push to the same object . If you push to the list , under the hood the list gets the data but React cannot rerender because the object listData does not save value but reference , which doesn't change . Creating a new object by copying all the data and putting it in a new object changes the reference of newreferenceListData ,which causes re render.

 function add(){
    let newrow = {};
    let newreferenceListData = [...listData,newrow];
    setlistData(newreferenceListData);
  }

If you want to understand , have an object as

let [state,setState]=useState({a:{b:{c:5}}})
  • Related