Reputation: 936
I have 3 elements and I want to add a new element by clicking on any div, but the problem is after adding new elements to the array they don't get rendered out of the component.
import React, { useState } from "react";
import "./styles.css";
export default function App() {
let elements = [
{ id: 0, text: "first" },
{ id: 1, text: "second" },
{ id: 2, text: "third" }
];
const [state, setstate] = useState(elements);
function handleClick() {
elements.push({ id: 3, text: "xxx", checkBox: null });
setstate(elements);
console.log(state); //state shows 4 elememnt but they don't render in
}
return (
<div className="App">
{state.map((e) => (
// why this don't render the new elements?
<div onClick={handleClick}>{e.text}</div>
))}
</div>
);
}
in codesandbox
https://codesandbox.io/s/beautiful-silence-c1t1k?file=/src/App.js:0-641
Upvotes: 0
Views: 48
Reputation: 76
You should not mutate the state directly
import React, { useState } from "react";
import "./styles.css";
const defaultElements = [
{ id: 0, text: "first" },
{ id: 1, text: "second" },
{ id: 2, text: "third" }
];
const newElement = {
id: 3,
text: "xxx",
checkBox: null
};
export default function App() {
const [state, setState] = useState(defaultElements);
function handleClick() {
setState((item) => [...item, newElement]);
}
return (
<div className="App">
{state.map(({ text }, index) => (
<div key={index} onClick={handleClick}>
{text}
</div>
))}
</div>
);
}
Upvotes: 1
Reputation: 15166
You should not mutate the state directly, it's not a good practice. Instead try as:
function handleClick() {
setstate(prevState => [
...prevState,
{ id: 3, text: "xxx", checkBox: null }
])
}
By doing this you are cloning the previous state of the array and adding that new element into the copy of the array what you can pass to setState
function.
See the working CodeSandbox here.
Upvotes: 2