REACT REDUX:更新深层嵌套对象中的值 [英] REACT REDUX: Update value in deep nested object

查看:132
本文介绍了REACT REDUX:更新深层嵌套对象中的值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试更新存储在深层嵌套对象中的值.它包含许多信息并且模式是固定的.我正在尝试复制对象,然后从输入返回具有更新值 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 来创建数组的副本而不对其进行变异.

https://redux.js.org/recipes/structuringreducers/immutableupdatepatterns#correct-approach-copying-all-levels-of-nested-data

https://redux.js.org/recipes/structuringreducers/immutableupdatepatterns#inserting-and-removing-items-in-arrays

将是帮助您更好地理解这一点的资源.

让我们假设你的 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.

https://redux.js.org/recipes/structuringreducers/immutableupdatepatterns#correct-approach-copying-all-levels-of-nested-data

and https://redux.js.org/recipes/structuringreducers/immutableupdatepatterns#inserting-and-removing-items-in-arrays

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆