переменная состояния имеет неправильное значение в функциональном компоненте

Я пытаюсь добавить и удалить поле ввода в форме. Я буду управлять этим ящиком с помощью хука useState. У меня нет проблем с добавлением переменной состояния, но когда я хочу удалить из переменной состояния, переменная состояния имеет неправильное значение.

import React, { useState } from 'react';
export default function Addable() {
  const [element, setElement] = useState([]);
  function add() {
    const list = [...element];
    const length = element.length;
    list.push(
      <React.Fragment>
        <input key={length} />
        <button onClick={()=>{_delete(length)}}>delete</button>
      </React.Fragment>,
    );
    setElement(list);
  }
  function _delete(index) {
    //****element has wrong value here****//
    const list = [...element];
    list.splice(index, 1);
    setElement(list);
  }
  return (
    <React.Fragment>
      <button onClick={add}>add Element</button>
      {element}
    </React.Fragment>
  );
}

1 ответ

Решение

Функция среза не изменитсяlist массив

const animals = ['ant', 'bison', 'camel', 'duck', 'elephant'];
animals.slice(2)
console.log(animals);

Вместо этого вы можете использовать splice, чтобы предотвратить проблему с закрытием, передайте функцию вsettlement установить состояние на текущее состояние

function _delete(index) {
    //****element has wrong value here****//
    console.log(element);
    setElement((currentEl) => {
      const list = [...currentEl];
      list.splice(index, 1);
      return list
    });
  }

ПРИМЕЧАНИЕ. Если вы используете неуправляемый компонент ввода, вам необходимо сгенерировать уникальный идентификатор для ввода и установить его в качестве ключа. потому что React проверит ключ, чтобы узнать, какой элемент нужно удалить. Например, у вас есть элемент длиной 5, затем вы удаляете индекс элемента2так что теперь элемент имеет длину 4, но индекс 2 все еще существует, поэтому React не знает, что вы удаляете индекс 2 (потому что ключ 2 все еще там), поэтому он сместится с 3 на 2, с 4 на 3.. Проверьте это для лучшего объяснения и демо

Вам нужно создать уникальный идентификатор, uuid в качестве выбора

function add() {
    const list = [...element];
    const length = element.length;
    const uniqueId = uuid()
    list.push(
     {id: uniqueId
      comp: () => (<React.Fragment>
        <input key={uniqueId} />
        // index is length-1
        <button onClick={()=>{_delete(uniqueId)}}>delete</button>
      </React.Fragment>)
     }
    );
    setElement(list);
  }

function _delete(elementId) {
   // Because we set new state on current state
   // it's better to pass an function into setElement like this to prevent some problem with closure
   setElement(currently =>{
      return currently.filter(el => el.id !== elementId );
    });
}
return (
  <React.Fragment>
    <button onClick={add}>add Element</button>
    {element.map(el => el.comp())}
  </React.Fragment>
);

Редактировать hidden-currying-hmh4m

Другие вопросы по тегам