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}}})