使用React Hooks更新状态数组对象的最佳方法



实际上我有一个元素列表,这些元素必须作为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})

相关内容

  • 没有找到相关文章

最新更新