在反应状态下替换数组中的对象
Replace object in array on react state
这个问题可能有点像"最佳实践"问题,但请耐心听我说。
这是我状态的一部分:
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
}...
我需要做的是在标题数组上的给定索引处替换对象。
我不知道如何与setState方法在this.setState(headers[1] = {obj})
-但这显然是无效的。我目前的方法是创建一个新数组,并像这样破坏旧数组:
_updateStyle(props) {
let newState = Object.assign({}, this.state)
newState.typeElements.headers[props.index] = props
this.setState(newState)
};
对于我的小hacky项目,我想这是可以的,但我觉得这是超级沉重的,会很快导致任何规模的性能问题。
已更新:由于这个答案仍然得到支持,请注意下面的前一个答案对于现代JavaScript和React来说已经过时了。"update"插件现在是遗留的,可以使用" immutable -helper"来代替。
React文档还提到了为什么不可变性很重要,以避免状态突变。对于不可变更新,您可以使用Object.assign()
或扩展语法,这需要在每一级嵌套中完成,例如在本例中嵌套的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文档中的类似示例也解释了"不可变更新模式"。
React对此提供了一些不变性帮助,请参见文档:https://facebook.github.io/react/docs/update.html
在您的情况下,您可以使用$splice命令删除一个项目和在给定索引处添加新索引,例如:
_updateStyle (props) { this.setState(update(this.state.typeElements, { $splice: [[props.index, 1, props]] } )); }
提供如何完成此操作的更好解释
- 首先,找到要替换的元素在状态数组中的索引。 第二,
- 第三,调用
setState
与新的集合
update
索引的元素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});
}
use immutability-helper
你可以在这里找到很好的例子
对象。赋值使用浅拷贝,而不是深拷贝。
请注意,在您的示例中,Object.assign({}, this.state)
仅复制到state
最近的子数组的链接,即typeElements
,但headers
数组不复制。
...
。Babel有一个特殊的附加项transform-object-rest-spread。let newHeaders = { ...this.state.typeElements.headers};
newHeaders[index] = props.Something;
let newState = {...state, typeElements: { newHeaders }};
- 将数组对象传递到struts2中的操作类
- 如何使用jquery返回php-json数组对象
- 从其名称获取javascript数组对象
- 值未与数组对象绑定
- 如何按数组/对象值的倍数过滤对象数组
- 在表中显示数组对象
- 在数组对象中分组
- 将第二个或多个数组推送到数组对象 AngularJS 中
- 重新排列 JavaScript 数组/对象
- 键上的javascript数组对象过滤器
- handontable:在不更改数据数组/对象的情况下隐藏某些列
- 用于跟踪购物车可用性的Javascript数组/对象/哈希表
- 重建有角度的java脚本数组对象
- 对JSON数组对象进行排序
- 连接与数组对象相关的文本:方式和位置
- 哪些浏览器和版本支持将常见的类数组对象直接传递到fn.apply()
- 如何使用Handlebars循环数组对象和模板
- 是否可以引用JS数组/对象中的另一个元素
- Javascript中的名称索引-数组/对象
- 数组长度不等于数组对象