Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

241
Visualizações
Why doesn't my UI properly rerender my deleted object?

I have a parent component that maps over a list state using an Input component

import "./styles.css";
import { useState, useEffect } from "react";
import Input from "./Input";

export default function App() {
  const [list, setList] = useState([{}]);
  useEffect(() => {
    console.log("list", list);
  }, [list]);
  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
      {list.map((_, i) => (
        <div key={i}>
          <Input id={i} setList={setList} />
        </div>
      ))}
    </div>
  );
}

Submitting each Input leaves another Input available for submission. However, when I delete each Input, I see that the data object is gone but the UI doesn't reflect this.

import { useState } from "react";

const Input = ({ setList, id }) => {
  const [value, setValue] = useState("");
  const [submitted, setSubmitted] = useState(false);
  const handleChange = (event) => {
    const result = event.target.value.replace(/\D/g, "");
    setValue(result);
  };
  const handleSubmit = () => {
    setList((list) => [...list, { id: id, total: value }]);
    setSubmitted(true);
  };
  const handleDelete = () => {
    console.log("id", id);
    setList((list) => list.filter((item) => item.id !== id));
  };
  return (
    <div>
      <input
        value={new Intl.NumberFormat("ko-KR", {
          style: "currency",
          currency: "KRW"
        }).format(Number(value))}
        onChange={handleChange}
        type="text"
      />
      {submitted ? (
        <button disabled={value.length === 0} onClick={handleDelete}>
          Delete
        </button>
      ) : (
        <button disabled={value.length === 0} onClick={handleSubmit}>
          Submit!
        </button>
      )}
    </div>
  );
};

export default Input;

I suspect that this is because

  const [list, setList] = useState([{}])

Is initialized with an empty object, and that is causing the problem. However, I need at least one object inside the list state so I can have the initial Input component for submission.

How do I properly delete my Input component?

My codesandbox

about 4 years ago · Juan Pablo Isaza
2 Respostas
Responde à pergunta

0

Your issue is with your key

<div key={i}></div>

React uses the key prop to help identify what elements have been changed. Keys should remain the same for each element in your array across re-renders, so that React can identify when an element has been updated based on a state change. As you're removing elements from your state, the index doesn't serve as a stable key that is uniquely associated with your object (as objects shift into lower indexes when one is removed). Instead, it's best to add some sort of id associated with the elements that you render:

const [list, setList] = useState([{ id: 0}]);
...
{list.map(({ id }) => (
  <div key={id}>
    <Input id={id} setList={setList} />
  </div>
))}
...

Then in your component where you add your objects, you can create a new id (which doesn't change) for each new object. Below I've used Math.random(), but you should use something more reliable than that (eg: uuidv4).

setList((list) => [...list, { id: Math.random(), total: value }]);

You should also look into how you're adding new values. The "submit" Input only appears because of the new object that you're adding to your list: { id: Math.random(), total: value }. I would instead have App display one Input which is primarily responsible for adding items to your list state, and then have each Input that is rendered within the .map() take care of the "delete" functionality.

about 4 years ago · Juan Pablo Isaza Relatório

0

This happen because you used index as a key in map.

You can read more about it here.

Long story short, for example you have 3 items, you delete second that has key "2", then your third element receive a key "2" and react think that this is the same element.

I updated your example with item template that have temp id set to "new item" and used id as a key.

Also I create id for each new element in handleSubmit function, so your temp id never became a real one.

Here is updated code. I removed some code that wasn't changed.

App component

const TEMPLATE = {
  id: "new item",
  value: 0,
}

export default function App() {
  const [list, setList] = useState([{...TEMPLATE}]);

  return (
    <div className="App">
      {list.map((item) => (
        <div key={item.id}>
          <Input id={item.id} setList={setList} />
        </div>
      ))}
    </div>
  );
}

And here is Input component. You would want to generate Id in some other way.

const Input = ({ setList, id }) => {
  ...
  const handleSubmit = () => {
    setList((list) => [...list, { id: Math.random(), total: value }]);
    setSubmitted(true);
  };
  ...    
};
about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda