在反应状态下替换数组中的 object
Replace object in array on react state
这个问题可能有点落在"best practice"问题的一边,但请耐心等待。
这是我的状态的一部分:
this.state = {
typeElements: {
headers: [
{
name: "h1",
size: 70,
lineHeight: 1.25,
kearning: 0,
marginAfter: 0
}, {
name: "h2",
size: 70,
lineHeight: 1.25,
kearning: 0,
marginAfter: 0
}, {
name: "h3",
size: 70,
lineHeight: 1.25,
kearning: 0,
marginAfter: 0
}...
我需要做的是在 headers 数组的给定索引处替换 object。
我不知道如何使用 this.setState(headers[1] = {obj})
中的 setState 方法来做到这一点 - 但这显然是无效的。我目前的方法是创建一个新数组并像这样破坏旧数组:
_updateStyle(props) {
let newState = Object.assign({}, this.state)
newState.typeElements.headers[props.index] = props
this.setState(newState)
};
对于我的小 hacky 项目,我想它还可以,但我觉得这太笨重了,会很快导致任何规模的性能问题。
Object.Assign使用的是浅拷贝,不是深拷贝。
请注意,在您的示例中,Object.assign({}, this.state)
仅复制指向 state
的最近子项的链接,即 typeElements
,但不会复制 headers
数组.
在 ES6 中有一个语法糖 ...
用于 Object.Assign,Babel 有一个特殊的插件 transform-object-rest-spread。
let newHeaders = { ...this.state.typeElements.headers};
newHeaders[index] = props.Something;
let newState = {...state, typeElements: { newHeaders }};
更新:因为这个答案仍然得到赞成票,请注意下面的先前答案对于现代 JavaScript 和 React 来说已经过时了。 "update" 插件现在是遗留的,可以使用 "immutability-helper" 代替。
React 文档还提到了为什么 immutability is important so avoid mutating state. For immutable updates you can use Object.assign()
or spread syntax 需要为每个嵌套级别完成,就像本例中嵌套的 headers
对象及其数组元素一样。在此特定示例中,我们可以使用数组索引作为键,因此也可以使用展开运算符对数组进行浅表克隆,并在克隆数组中的给定索引处分配一个新对象作为值。
_updateStyle (props) {
const { typeElements } = this.state;
const updatedHeaders = [...typeElements.headers];
updatedHeaders[props.index] = props;
this.setState({
...this.state,
typeElements: {
...typeElements,
headers: updatedHeaders
}
));
}
另一个不需要扩展语法的解决方案,如果我们不使用数组索引来查找我们想要替换的对象,则需要使用 array.map
创建一个新数组并返回给定索引处的新对象而不是旧对象。
const updatedHeaders = typeElements.headers.map((obj, index) => {
return index === props.index ? props : obj;
});
Redux 文档中的类似示例也解释了 "immutable update patterns"。
React has some immutability helpers for this, which is explained in
the docs: https://facebook.github.io/react/docs/update.html
In your case you could use the $splice command to remove one item and
add the new one at given index, for example:
_updateStyle (props) {
this.setState(update(this.state.typeElements,
{ $splice: [[props.index, 1, props]] }
));
}
你可以在那里找到很好的例子
更好地解释如何实现这一点。
- 首先,找到您要替换的元素在状态数组中的索引。
- 其次,
update
那个索引处的元素
- 三、调用
setState
新集合
import update from 'immutability-helper';
// this.state = { employees: [{id: 1, name: 'Obama'}, {id: 2, name: 'Trump'}] }
updateEmployee(employee) {
const index = this.state.employees.findIndex((emp) => emp.id === employee.id);
const updatedEmployees = update(this.state.employees, {$splice: [[index, 1, employee]]}); // array.splice(start, deleteCount, item1)
this.setState({employees: updatedEmployees});
}
这个问题可能有点落在"best practice"问题的一边,但请耐心等待。
这是我的状态的一部分:
this.state = {
typeElements: {
headers: [
{
name: "h1",
size: 70,
lineHeight: 1.25,
kearning: 0,
marginAfter: 0
}, {
name: "h2",
size: 70,
lineHeight: 1.25,
kearning: 0,
marginAfter: 0
}, {
name: "h3",
size: 70,
lineHeight: 1.25,
kearning: 0,
marginAfter: 0
}...
我需要做的是在 headers 数组的给定索引处替换 object。
我不知道如何使用 this.setState(headers[1] = {obj})
中的 setState 方法来做到这一点 - 但这显然是无效的。我目前的方法是创建一个新数组并像这样破坏旧数组:
_updateStyle(props) {
let newState = Object.assign({}, this.state)
newState.typeElements.headers[props.index] = props
this.setState(newState)
};
对于我的小 hacky 项目,我想它还可以,但我觉得这太笨重了,会很快导致任何规模的性能问题。
Object.Assign使用的是浅拷贝,不是深拷贝。
请注意,在您的示例中,Object.assign({}, this.state)
仅复制指向 state
的最近子项的链接,即 typeElements
,但不会复制 headers
数组.
在 ES6 中有一个语法糖 ...
用于 Object.Assign,Babel 有一个特殊的插件 transform-object-rest-spread。
let newHeaders = { ...this.state.typeElements.headers};
newHeaders[index] = props.Something;
let newState = {...state, typeElements: { newHeaders }};
更新:因为这个答案仍然得到赞成票,请注意下面的先前答案对于现代 JavaScript 和 React 来说已经过时了。 "update" 插件现在是遗留的,可以使用 "immutability-helper" 代替。
React 文档还提到了为什么 immutability is important so avoid mutating state. For immutable updates you can use Object.assign()
or spread syntax 需要为每个嵌套级别完成,就像本例中嵌套的 headers
对象及其数组元素一样。在此特定示例中,我们可以使用数组索引作为键,因此也可以使用展开运算符对数组进行浅表克隆,并在克隆数组中的给定索引处分配一个新对象作为值。
_updateStyle (props) {
const { typeElements } = this.state;
const updatedHeaders = [...typeElements.headers];
updatedHeaders[props.index] = props;
this.setState({
...this.state,
typeElements: {
...typeElements,
headers: updatedHeaders
}
));
}
另一个不需要扩展语法的解决方案,如果我们不使用数组索引来查找我们想要替换的对象,则需要使用 array.map
创建一个新数组并返回给定索引处的新对象而不是旧对象。
const updatedHeaders = typeElements.headers.map((obj, index) => {
return index === props.index ? props : obj;
});
Redux 文档中的类似示例也解释了 "immutable update patterns"。
React has some immutability helpers for this, which is explained in the docs: https://facebook.github.io/react/docs/update.html
In your case you could use the $splice command to remove one item and add the new one at given index, for example:
_updateStyle (props) { this.setState(update(this.state.typeElements, { $splice: [[props.index, 1, props]] } )); }
你可以在那里找到很好的例子
更好地解释如何实现这一点。
- 首先,找到您要替换的元素在状态数组中的索引。
- 其次,
update
那个索引处的元素 - 三、调用
setState
新集合
import update from 'immutability-helper';
// this.state = { employees: [{id: 1, name: 'Obama'}, {id: 2, name: 'Trump'}] }
updateEmployee(employee) {
const index = this.state.employees.findIndex((emp) => emp.id === employee.id);
const updatedEmployees = update(this.state.employees, {$splice: [[index, 1, employee]]}); // array.splice(start, deleteCount, item1)
this.setState({employees: updatedEmployees});
}