我有一个在React状态下更新嵌套对象的函数,并且有一个可行的解决方案,但我正在寻找更精致的东西。
这是我的状态结构:
state: {
...someState,
object: [
{
key1: "1",
key: "2",
key3: "3",
key4: "4"},
{
key1: "1",
key: "2",
key3: "3",
key4: "4"}]
}
当前我正在使用此功能来更新状态:
handleInputChange = (
e: ChangeEvent<HTMLInputElement>,
name: FilterKeys,
subname?: any,
index?: number
) => {
e.persist();
if (subname && index !== undefined) {
let prop: SomeKeys;
prop = subname;
const editedObject = Object.assign({}, this.state.object);
editedObject[index][prop] = e.target.value;
const object = Object.keys(editedObject).map((e: any) => {
return editedObject[e];
});
this.setState(
(prevState: I) => ({
...prevState,
object
}),
() => {
this.someCallback()
}
);
}
};
我的目标是做这样的事情:
handleInputChange = (
e: ChangeEvent<HTMLInputElement>,
name: FilterKeys,
subname?: any,
index?: number
) => {
e.persist();
if (subname && index !== undefined) {
let prop: SomeKeys;
prop = subname;
this.setState((prevState)=>{
object: [...prevState.object, prevState.object[index][prop]:3]
})
}
}
};
希望您能理解我的意思。我也知道一种解决方案,可以在其中分配一些键给对象,这样我就可以访问它,但是我对这样的语法很感兴趣,因为imo看起来更干净
p.s对象数组的长度取决于用户
答案 0 :(得分:0)
您可以使用第三方库吗? 我推荐https://lodash.com/docs/4.17.11#set。由于您需要具有不可变的状态,因此可以使用lodash / fp(https://github.com/lodash/lodash/wiki/FP-Guide):
import set from 'lodash/fp/set'
//...
this.setState(
currentState => set(['object', index, prop], e.target.value, currentState)
)
set
是lodash.fp函数。第一个参数是要设置的属性的路径,第二个参数是新值,第三个参数是要更新的对象。 Lodash / fp总是创建一个NEW对象。
如果您了解函数式编程的用法,则可以将这种构造简化为
this.setState(
set(['object', index, prop], e.target.value)
)
另一种解决方案
当然,您可以在没有外部库的情况下做到这一点:
this.setState(prevState => ({
...prevState,
object: [
...prevState.object.slice(0, index),
{
...prevState.object[index],
[prop]: e.target.value,
},
...prevState.object.slice(index + 1),
],
}))
答案 1 :(得分:0)
仅从key3
更新object[0]
:
const newState = {
...state,
object:[
...state.object,
[0] : {
...state.object[0],
key3: newValue
}
]
}
答案 2 :(得分:0)
虽然没有您希望的那么简洁,但是我认为这应该可以解决问题。
它将原始数组映射为新对象的数组,如果索引与当前迭代匹配,则它将给定“键”的值覆盖为事件目标的值。
handleInputChange = (
e: ChangeEvent<HTMLInputElement>,
name: FilterKeys,
subname?: any,
index?: number
) => {
e.persist();
if (subname && index !== undefined) {
const prop: SomeKeys = subname;
const newObjArray = this.state.object
.map((obj, i) => ({
...obj,
[prop]: i !== index ? obj[prop] : event.target.value
}));
this.setState((prevState)=>{
object: newObjArray
});
}
}