REACT REDUX:更新深层嵌套对象中的值 [英] REACT REDUX: Update value in deep nested object
问题描述
我正在尝试更新存储在深层嵌套对象中的值.它包含许多信息并且模式是固定的.我正在尝试复制对象,然后从输入返回具有更新值 onChange 的对象.但是我无法成功正确复制完整树并返回更新的内容.
演示:https://codesandbox.io/s/4j7x8jlk9w
对象看起来像:
内容:{标签:标签",模板: [{名称:示例",类型:类型",项目: [{键:键1",特性: {文本: {标签:标签1",价值:价值1"},颜色: {标签:颜色",值:#123"}}},{键:键2",特性: {文本: {标签:标签2",价值:价值2"},颜色: {标签:颜色",值:#456"}}}]}]}
减速器:
case "UPDATE_VALUE":const content = state.content.templates[state.templateKey].items[状态.itemKey].properties.text.value =行动价值;返回 { ...状态,内容};默认:返回状态;}
组件:
import React, { PureComponent } from "react";从react-redux"导入{连接};从./actions"导入 { updateValue };class Page 扩展 PureComponent {使成为() {const { content, templateKey, itemKey } = this.props;返回 (<div><h1风格={{颜色:content.templates[templateKey].items[itemKey].properties.color.价值}}>{content.templates[templateKey].items[itemKey].properties.text.value}<输入name={content.templates[templateKey].items[itemKey].key}值={content.templates[templateKey].items[itemKey].properties.text.value}onChange={e =>this.props.updateValue(e.target.name, e.target.value)}/>
);}}const mapStateToProps = state =>({内容:state.content,模板密钥:state.templateKey,itemKey: state.itemKey});const mapDispatchToProps = dispatch =>({更新值:(键,值)=>调度(更新值(键,值))});导出默认连接(mapStateToProps,mapDispatchToProps)(页);
对于这样的深度嵌套数据,您可以在树的每个深度使用扩展语法,直到到达您想要更改的内容.对于数组,您可以使用 slice
来创建数组的副本而不对其进行变异.
将是帮助您更好地理解这一点的资源.
让我们假设你的 reducer 有一个要更新的模板的索引,以及该模板中要更新的项目的索引.您的代码可能如下所示:
return {...状态,模板: [...state.templates.slice(0, templateIndex),{...state.templates[templateIndex],项目: [...state.templates[templateIndex].items.slice(0, itemIndex),{...state.templates[templateIndex].items[itemIndex],价值:行动.价值},...state.templates[templateIndex].items.slice(itemIndex)]},...state.templates.slice(templateIndex)]}
如您所见,当您处理这样的嵌套数据时,它会变得非常混乱.建议您规范化嵌套数据,以使您的减速器无需做更少的工作即可找到要更改的内容.
这是您更新的代码和框:https://codesandbox.io/s/w77yz2nzl5
I am trying to update a value stored in a deep nested object. It contains many pieces of information and the schema is fixed. I am trying to copy the object then return the object with update value onChange from an input. However I am unable to successfully correctly copy the full tree and return the updated content.
DEMO: https://codesandbox.io/s/4j7x8jlk9w
the object looks like:
content: {
label: "Label",
templates: [
{
name: "example",
type: "the type",
items: [
{
key: "key1",
properties: {
text: {
label: "The Label 1",
value: "The Value 1"
},
color: {
label: "Color",
value: "#123"
}
}
},
{
key: "key2",
properties: {
text: {
label: "The Label 2",
value: "The Value 2"
},
color: {
label: "Color",
value: "#456"
}
}
}
]
}
]
}
The Reducer:
case "UPDATE_VALUE":
const content = state.content.templates[state.templateKey].items[
state.itemKey
].properties.text.value =
action.value;
return { ...state, content };
default:
return state;
}
The Component:
import React, { PureComponent } from "react";
import { connect } from "react-redux";
import { updateValue } from "./actions";
class Page extends PureComponent {
render() {
const { content, templateKey, itemKey } = this.props;
return (
<div>
<h1
style={{
color:
content.templates[templateKey].items[itemKey].properties.color
.value
}}
>
{content.templates[templateKey].items[itemKey].properties.text.value}
</h1>
<input
name={content.templates[templateKey].items[itemKey].key}
value={
content.templates[templateKey].items[itemKey].properties.text.value
}
onChange={e => this.props.updateValue(e.target.name, e.target.value)}
/>
</div>
);
}
}
const mapStateToProps = state => ({
content: state.content,
templateKey: state.templateKey,
itemKey: state.itemKey
});
const mapDispatchToProps = dispatch => ({
updateValue: (key, value) => dispatch(updateValue(key, value))
});
export default connect(
mapStateToProps,
mapDispatchToProps
)(Page);
With deeply nested data like this, you can use the spread syntax at each depth of the tree until you arrive at the thing you want to change. For arrays, you can use slice
to create a copy of the array without mutating it.
will be resources to help you understand this better.
Let's assume your reducer is given an index for which template to update, and an index for which item to update within that template. Your code might look like this:
return {
...state,
templates: [
...state.templates.slice(0, templateIndex),
{
...state.templates[templateIndex],
items: [
...state.templates[templateIndex].items.slice(0, itemIndex),
{
...state.templates[templateIndex].items[itemIndex],
value: action.value
},
...state.templates[templateIndex].items.slice(itemIndex)
]
},
...state.templates.slice(templateIndex)
]
}
As you can see, it gets pretty messy when you're dealing with nested data like this. It's recommended that you normalize nested data to make your reducers have to do less work to find the thing to change.
Here's your updated codesandbox: https://codesandbox.io/s/w77yz2nzl5
这篇关于REACT REDUX:更新深层嵌套对象中的值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!