Ali Husham
Ali Husham

Reputation: 936

Component doesn't return the new elements after updating state?

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

Answers (2)

Maxim Nikitenko
Maxim Nikitenko

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

norbitrial
norbitrial

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

Related Questions