如何在 React 中使用 useState Hook 更改/添加数组的某一行的值
Posted
技术标签:
【中文标题】如何在 React 中使用 useState Hook 更改/添加数组的某一行的值【英文标题】:How to change/add value of a certain row of an array using useState Hook in React 【发布时间】:2021-10-21 19:51:14 【问题描述】:我有一个如下数组,
const bio = [
id: 1, name: "Talha", age: 26,
id: 2, name: "Ayub", age: 22
]
这是我的完整代码,
import './App.css';
import React, useState from 'react';
const bio = [
id: 1, name: "Talha", age: 26,
id: 2, name: "Ayub", age: 22
]
const App = () =>
const [bioData, setbioData] = useState(bio);
const clear_function = () => setbioData([])
return (
<div className="App">
bioData.map((arr) =>
<>
<h3 key=arr.id>Name: arr.name, Age: arr.age</h3>
<button onClick=() => clear_function()>Click me</button>
</>
)
</div>
);
export default App;
现在,这段代码将整个数组与 useState 挂钩。每当我单击“单击我”按钮时,它会将状态设置为空数组并返回空数组。
但是如果我想删除数组的特定行怎么办?我做了两个按钮,每个按钮一排。我想要做的是,如果我单击第一个按钮,它也会从数组中删除第一行并保留第二个数组。
同样,如果我想更改特定行的特定属性值,我该如何使用 useState 挂钩呢?例如,我想更改第二行的name属性。 useState 怎么可能做到这一点?
加法也是一样的。如果我制作一个表格并尝试在我的生物数组中添加一个新行,我该怎么做? 我在谷歌上搜索了它,也找到了一个类似的帖子,但其中给出的答案并不令人满意,也没有奏效,这就是我再次问这个问题的原因。
【问题讨论】:
【参考方案1】:使用 react useState 向数组中添加一行就像下面这样简单:
function addRow(objToAdd)
//get old data and add new row
let newBioData = bioData.push(objToAdd)
setBioData(newBioData)
要删除特定行,您需要在 bioData 数组中找到对象,将其删除并设置新的 bioData,如下所示:
function removeRow(rowId)
//Filter the array by returning every object with a different Id than the one you want to remove
let newBioData = bioData.filter(function (value, index, arr) return value.id != rowId )
setBioData(newBioData)
要更新状态,您可以像这样使用扩展运算符:
function updateRow(rowId, data)
//Iterate list and update certain row
bioData.filter(function (value, index, arr)
//Row to update
if(value.id == rowId)
return name: data.name, age: data.age
else
//Nothing to update, return current item (spread all values)
return ...value
)
setBioData ([])
【讨论】:
感谢您的回复。我理解这些并且也已经实施了它们,它们就像你说的那样工作。但我的问题是如何更新特定的行值?例如,我想将 bioData[1].name 的值更新为不同的值。如何使用 useState 钩子和 Button 的 onClick 来做到这一点。 我已经更新了我的帖子,希望对你有帮助! :)【参考方案2】:我不确定我是否完全理解您的问题,但是当您想更改功能组件中的状态时,您不能直接更改状态对象,而是需要创建一个新的所需状态对象,并且然后将状态设置为该对象。 例如,如果您想向数组中添加新行,您将执行以下操作:
setbioData((currBioData) => [...oldBioData, id: 3, name: "Bla", age: 23]);
当您想根据当前状态更改状态时,可以选择向setState
函数发送一个接受当前状态的回调函数,然后使用扩展运算符向数组中添加一个新行。
我不打算讨论为什么最好通过 setState
一个函数来修改当前状态,但你可以在 React official docs 中阅读它
【讨论】:
这行得通,谢谢。但我的主要问题是,如何更新特定的行值?例如,我想将 bioData[1].name 的值更新为不同的值。如何使用 useState 钩子和 Button 的 onClick 来做到这一点。【参考方案3】:这里似乎有 3 个问题。我会尽力帮忙的。
“如果我想删除数组的特定行怎么办?”
一种方法是过滤当前数组并使用新数组更新状态。
在您的示例中:onClick=()=>setbioData(arr.filter(row=>row.id !== arr.id))
“如果我想更改特定行的特定属性值,我该如何使用 useState 挂钩?”
您将需要使用正确的信息创建一个新数组并将该数组保存到 state。
在您的示例中:[... bioData, id:/row_id/,name:/new name/,age:/new age/]
“如果我创建一个表单并尝试在我的 bio 数组中添加一个新行,我将如何做” 在这种情况下,您会将一个新对象推送到您的数组中。在您的示例中:
setbioData(previousData=>previousData.push(id:previousData.length+1,name:/new name/,age:/new age/)
希望对你有帮助,祝你好运
【讨论】:
感谢您的回复。我完全理解移除和插入部分,它们也为我工作。我唯一的问题是,如何在更新行的情况下进行检查?确保仅更新特定行(单击哪个按钮)的检查?例如,如果按钮的 id = 2,则更新我的数组的第二行,而不是任何其他 这是一个非常相似的问题,答案比我能给出的要好。我希望它有帮助! ***.com/questions/28121272/…【参考方案4】:import './App.css';
import React, useState from 'react';
const bio = [
id: 1, name: "Talha", age: 26,
id: 2, name: "Ayub", age: 22
]
const App = () =>
const [bioData, setbioData] = useState(bio);
const clear_function = (i) =>
let temp = bioData.slice()
temp = temp.splice(i, 1)
setbioData(temp)
return (
<div className="App">
bioData.map((arr, i) =>
<>
<h3 key=arr.id>Name: arr.name, Age: arr.age</h3>
<button onClick=() => clear_function(i)>remove row</button>
</>
)
</div>
);
export default App;
同样的方式,你只需要更新一个特定的属性,只需更新 temp 数组中的那个元素并执行 setBioData(temp)
同样,如果你想添加另一行,请执行 temp.push(id: 1, name: "Talha", age: 26) 并执行 setBioData(temp)
【讨论】:
我试过这个实现。它适用于删除一行,谢谢。但不幸的是,当我尝试更新特定行的值时它不起作用。例如,我在clear_function
函数中做了这个:let temp = bioData.slice()
temp[1].name = "Hello World";
setbioData(temp)
。但它没有更新第二行的名称。【参考方案5】:
如果我理解正确的问题,我认为您可以将更新的对象传递给设置状态,就是这样。
要更改数组中的特定对象,请执行以下操作:
// Update bio data with id = 2
setbioData(prevValue =>
[...prevValue].map(el =>
el.id === 2 ? (...el, name:'new name') : el)
)
另外,你把key
设错了地方
完全重构的代码:
const bio = [
id: 1, name: "Talha", age: 26,
id: 2, name: "Ayub", age: 22
]
const App = () =>
const [bioData, setbioData] = useState(bio);
const clear_function = (id) =>
setbioData(prevValue =>
[...prevValue].map(el =>
el.id === id ? (...el, name:'new name') : el)
)
return (
<div className="App">
bioData.map((arr) =>
<div key=arr.id>
<h3>Name: arr.name, Age: arr.age</h3>
<button onClick=() => clear_function(arr.id)>Click me</button>
</div>
)
</div>
);
【讨论】:
这对我不起作用:/我试图这样做...<button onClick=() => setbioData(bioData=> [...bioData].map(e1 => e1.id === 2 && e1.name='new name')) type="button">Click me</button>
...它在 e1 上出现错误,即Parsing error: Invalid left-hand side in assignment expression
。并在 e1.name 和 </button>
上给出错误。我似乎无法理解问题
@TalhaAyub 我已经更新了代码,看看。以上是关于如何在 React 中使用 useState Hook 更改/添加数组的某一行的值的主要内容,如果未能解决你的问题,请参考以下文章
如何使用映射 React 从 useState 添加 2 个键?
如何在 react native 中使用选择器从 redux 状态设置 usestate 的初始值?
如何在 React 中使用 useState Hook 更改/添加数组的某一行的值
如何在 React 函数组件(useState 挂钩)中访问 ag-Grid API?
如何使用 useState 在点击时显示/隐藏移动导航栏? React + TypeScript + Tailwind 项目