【问题标题】:Trouble updating UI with React useState when updating an array of items更新项目数组时使用 React useState 更新 UI 时出现问题
【发布时间】:2020-11-25 04:13:28
【问题描述】:

很难用 React 和 useState 更新我的 UI。任何帮助将不胜感激。基本上我想要做的只是删除用户添加的项目。

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>
 )
})}

【问题讨论】:

    标签: reactjs typescript use-state


    【解决方案1】:

    几点:

    1. 组件应返回单个元素。在您的情况下, map 返回一个元素数组,我必须使用一个空元素(或 <React.Fragment>)包装该集合
    2. 不要忘记将value 属性设置为input 元素,以使更改反映在元素中。
    3. 作为最佳实践,在处理状态变量时使用 const 而不是 let,将它们视为不可变的,以避免丢失更改,尤其是在有许多状态变量导致多次渲染时
    4. 我们应该说明类型,因为文件是打字稿,您错过了指定函数参数的类型
    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;
    
    

    【讨论】:

    • Christie 感谢您的反馈,谢谢。将 value={item.url} 添加到输入时,您无法再输入其中的几件事。其次,如果您单击删除,它将首先删除最后一项,然后是第二项,然后是第一项
    • 嘿@GalacticRanger 对此感到抱歉。请参阅更新的答案。我没有看到您描述的与删除项目相关的行为。你指的是同一个代码吗?
    • 克里斯蒂成功了,非常感谢你,一段时间以来一直在努力解决这个问题。
    • 很高兴帮助@GalacticRanger :-)
    猜你喜欢
    • 2020-07-20
    • 1970-01-01
    • 1970-01-01
    • 2020-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-23
    • 1970-01-01
    相关资源
    最近更新 更多