这个问题可能会落在“最佳实践”的一边。问题,但请耐心等待。
这是我州的一部分:
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数组的给定索引处替换对象。
我不知道如何使用this.setState(headers[1] = {obj})
中的setState方法做到这一点 - 但这显然无效。我目前的方法是创建一个新的数组并破坏旧的数组:
_updateStyle(props) {
let newState = Object.assign({}, this.state)
newState.typeElements.headers[props.index] = props
this.setState(newState)
};
对于我的小型hacky项目,我认为没关系,但我觉得这是非常沉重的,并且会很快导致任何规模的性能问题。
答案 0 :(得分:11)
更新:由于这个答案仍然得到了回复,请注意以下的答案已经过时了现代JavaScript和React。 “更新”插件现在已成为旧版,而"immutability-helper"可以替代使用。
React文档还提到了为什么immutability is important所以避免变异状态。对于不可变更新,您可以使用Object.assign()
或spread syntax,这需要针对每个嵌套级别进行,例如嵌套的headers
对象及其数组元素。在这个特定的例子中,我们可以使用数组索引作为键,因此也可以使用spread运算符来生成数组的浅层克隆,并在克隆数组中的给定索引处将新对象指定为值。
_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为此提供了一些不变的助手,其解释如下 文档:https://facebook.github.io/react/docs/update.html
在您的情况下,您可以使用$ splice命令删除一个项目 在给定索引处添加新的,例如:
_updateStyle (props) { this.setState(update(this.state.typeElements, { $splice: [[props.index, 1, props]] } )); }
答案 1 :(得分:2)
你可以在那里找到很好的例子
答案 2 :(得分:0)
Object.Assign使用浅拷贝,而不是深拷贝。
请注意,在您的示例Object.assign({}, this.state)
中,只复制指向最近的state
子项的链接,即typeElements
,但headers
数组不会被复制。< / p>
ES6中的Object.Assign有一个语法糖...
,Babel有一个特殊的插件transform-object-rest-spread。
let newHeaders = { ...this.state.typeElements.headers};
newHeaders[index] = props.Something;
let newState = {...state, typeElements: { newHeaders }};
答案 3 :(得分:0)
提供更好的解释如何实现这一目标。
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});
}