Проблема с обновлением пользовательского интерфейса с помощью React useState при обновлении массива элементов

#reactjs #typescript #use-state

#reactjs #typescript #use-state

Вопрос:

Мне трудно обновлять свой пользовательский интерфейс с помощью React и useState. Любая помощь будет с благодарностью. По сути, я пытаюсь просто удалить элемент, добавленный пользователем.

 interface RedirectUrls {
 url: string;
}

const [redirectUrls, setRedirectUrls] = useState<RedirectUrls[]>([
 {
  url: ''
 }
])

function deleteRedirectUrl(url): void {
 let tmpUrls = redirectUrls
 tmpUrls = tmpUrls.filter(item => item.url !== url)
 setRedirectUrls(tmpUrls)
}

function handleChange (index, event): void {
 const tmpUrls = [...redirectUrls]
 tmpUrls[index].url = event.target.value
}

{redirectUrls.map((item, index) => {
 return (
  <div key={index}>
   <input type='text' onChange={(event):void => {handleChange(index,event)}}/>
   <div onClick={():void => {deleteRedirectUrl(item.url)}}>remove</div>
  </div>
 )
})}
 

Ответ №1:

Несколько моментов:

  1. Компонент должен возвращать один элемент. В вашем случае map возвращает массив элементов, и мне пришлось обернуть коллекцию, используя пустой элемент (или <React .Фрагмент>)
  2. Не забудьте присвоить value свойству значение input element, чтобы изменения отражались в элементе.
  3. В качестве наилучшей практики используйте const вместо let того, чтобы при работе с переменными состояния рассматривать их как неизменяемые, чтобы избежать потери ваших изменений, особенно когда есть много переменных состояния, вызывающих множественные рендеринги
  4. Мы должны указать типы, поскольку файл является typescript, вы пропустили указание типов для аргументов ваших функций
  5. Следует вызвать установщик после внесения изменений
 import React, { useState } from 'react';

interface RedirectUrls {
  url: string;
}

const App = () => {
  const [redirectUrls, setRedirectUrls] = useState<RedirectUrls[]>([
    {
      url: 'firstUrl'
    },
    {
      url: 'secondUrl'
    }
  ])
  function deleteRedirectUrl(url: string): void {
    const tmpUrls = redirectUrls.filter(item => item.url !== url)
    setRedirectUrls(tmpUrls)
  }

  function handleChange(index: number, event: React.ChangeEvent<HTMLInputElement>): void {
    const tmpUrls = [...redirectUrls]
    tmpUrls[index].url = event.target.value
    setRedirectUrls(tmpUrls);
  }

  return <>{redirectUrls.map((item, index) => <div key={index}>
    <input type='text' value={item.url} onChange={(event): void => { handleChange(index, event) }} />
    <div onClick={(): void => { deleteRedirectUrl(item.url) }}>remove</div>
  </div>)}</>;
}


export default App;

 

Комментарии:

1. Кристи, я ценю ваше мнение, спасибо. Пара вещей при добавлении значения ={item.url} к входным данным, которые вы больше не можете вводить в него. Во-вторых, если вы нажмете на удаление, сначала удаляется последний элемент, затем второй элемент, а затем первый элемент

2. Привет, @GalacticRanger, извините за это. Смотрите обновленный ответ. Я не вижу поведения, которое вы описываете, связанного с удалением элементов. Вы имеете в виду тот же код?

3. Кристи, которая сделала свое дело, большое вам спасибо, уже некоторое время борется с этим.

4. Рад помочь @GalacticRanger 🙂