实际上我有一个元素列表,这些元素必须作为react状态存储到数组中。
const [data, setData] = useState([{"name": "joy", "age": 25}, {"name": "tom", "age": 41}]);
不知何故,我只需要更新一个特定的对象,可能是名称或年龄。
我就是这样做的。但这似乎并不好。
setData(prevState => {
let obj = prevState.find(o => anycondition);
if(obj !== undefined) {
obj.name = "Demo";
}
return [...prevState];
})
有没有其他方法可以使用React Hooks只更新状态数组中的对象?
这样做是一种状态突变!!
setData(prevState => {
let obj = prevState.find(o => anycondition);
if(obj !== undefined) {
obj.name = "Demo"; // <-- state mutation
}
return [...prevState];
})
应始终浅拷贝正在更新的的当前状态
setData(prevState => {
return prevState.map(el => <condition> ? { // <-- map state to new array
...el, // <-- copy element
name: "Demo", // <-- write new property
} : el);
})
如果需要在映射回调中进行任何计算,请为回调提供一个正常的函数体,并添加所需的任何逻辑。
setData(prevState => {
return prevState.map(el => { // <-- map state to new array
// any mapping logic
...
if (<condition>) {
// any other logic
...
return {
...el, // <-- copy element
name: "Demo", // <-- write new property
}
} else {
return el;
}
});
})
也许你想要这样的东西?
在这里,你将只循环一次,并更新你想要的数据
changeHandler = event => {
const [name, value] = event.target.name
setData(prevState => prevState.map(item => {
if (anycondition) {
return {
...item,
[name]: value
}
}
return item
}))
}
如果你也想从输入中获得一些id,你可以用数据集传递它,比如这里的data-id={1}
然后从changeHandler
函数中的类似const id = e.target.dataset.id;
的事件中获取
<input
type="text"
name="name"
data-id={1}
value={this.state.data.name.fname}
onChange={this.changeHandler}
/>
要用更多的控制来处理此问题,可以为每个对象添加一个id道具。
如果你想更改/修改一个特定的对象,只需执行:
const [data, setData] = useState([
{
id: 1,
name: "joy",
age: 25
},
{
id: 2,
name: "tom",
age: 41
}
]);
const updateItem = (id, attributes) => {
const index = data.findIndex(item => item.id === id);
if (index === -1)
return;
setData(
[
...data.slice(0, index),
Object.assign({}, data[index], attributes),
...data.slice(index + 1)
]
);
}
// You can update the second item as follows
updateItem(2, { age: 50 })
试试这种方法;(
function mergeState(state, payload) {
return { ...state, ...payload }
}
const [state, dispatch] = useReducer(mergeState, {
name: '',
age: 0,
data: [{"name": "joy", "age": 25}, {"name": "tom", "age": 41}],
})
// get the data
const data = state.data.map(item => {
if(obj !== undefined){
obj.name = "Demo";
}
return item
})
// update
dispatch({data})