根据对象数组形成组件 [英] Forming the components based on the array of objects

查看:71
本文介绍了根据对象数组形成组件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于应用程序的设置页面,我实现了一个启用(绿色)或禁用(红色)状态的滑块.并且父级的设置是根据其子级的值计算的.

//获取componnetDidMount里面的开关配置是这样的var obj = [{parent_header_name: "parent1",儿童信息:[{child_switch_name: "child1",已启用:真},{child_switch_name: "child2",已启用:假}]},{parent_header_name: "parent2",儿童信息:[{child_switch_name: "child3",已启用:真}]},{parent_header_name: "parent3",儿童信息:[{child_switch_name: "child4",已启用:假}]}];

现在基于这个值,我需要像这样形成一个父子组:

Label(value 应该是 parent_header_name) : Parent Switch Component儿童标签(children_switch_name):子开关组件

此外,在更改单个孩子的开关切换时,我需要获取该开关的信息,如下所示:

例如,将 parent1 的 child1 更改为禁用

<预><代码>[{parent_header_name: "parent1",儿童信息:[{child_switch_name: "child1",已启用:假}]}];

如果 parent1 已启用,我需要获取其所有 chidren 值

<预><代码>[{parent_header_name: "parent1",儿童信息:[{child_switch_name: "child1",已启用:真},{child_switch_name: "child2",已启用:真}]}]

当父母开关被切换时(当父母被启用时,孩子将被启用,当被禁用的孩子将被禁用;),我需要获得该父母的完整信息

此外,我需要避免切换到部分"状态,只应启用或禁用父级.部分"只是代表性的

为此,我为此切换开关使用了 react-multi-toggle.

我尝试过这样的事情:https://codesandbox.io/s/父子开关-gxfx6

解决方案

您可以重构您的 Setting 组件 以允许它根据呈现您的开关名称和值从 API 接收的数据.我建议您为每个 switches group 添加一个 id,这将简化您的工作.这里是分叉的工作沙箱.可以优化代码以适合您的用例.关键更改在 Setting Component 中完成.

设置组件完整代码

import React, { Component, Fragment } from "react";从lodash.isequal"导入 isEqual;从./ChildSwitch"导入 ChildSwitch;从./ParentSwitch"导入ParentSwitch;从./constant"导入{部分};导出默认类设置扩展组件{状态 = {父母:{价值:this.props.children.length >1?部分的: this.props.children[0].isEnabled},儿童:this.props.children};componentDidMount() {this.setParentSwitchValue();}shouldComponentUpdate(nextProps, nextState) {返回 !isEqual(this.state, nextState);}setChildSwitchValue = (id, isEnabled) =>{让 clickedChild;这个.setState(上一个状态 =>({...prevState,儿童:prevState.children.map(child => {如果(child.id === id){clickedChild = { ...child, isEnabled: isEnabled };返回 clickedChild;} 别的 {返回孩子;}})}),() =>this.setParentSwitchValue(clickedChild));};setParentSwitchValue = clickedChild =>{const { children } = this.state;让 parentVal = PARTIAL;if (children.every(({ isEnabled }) => isEnabled === true)) {parentVal = 真;}if (children.every(({ isEnabled }) => isEnabled === false)) {parentVal = 假;}这个.setState(上一个状态 =>({...prevState,父母:{值:parentVal}}),() =>{this.handleChange();如果(clickedChild){常量更改 = {父母:{名称:this.props.name,值:parentVal},孩子:clickedChild};console.log("这是改变的孩子", changed);}});};setChildrenValue = 值 =>{这个.setState(上一个状态 =>({...prevState,父母:{价值},儿童:prevState.children.map(child => ({...孩子,isEnabled:值}))}),this.handleChange);};handleChange = () =>{const { id, onChange } = this.props;onChange(id, this.state);};handleParentClick = parentVal =>{如果(parentVal !== 部分){this.setChildrenValue(parentVal);}};使成为() {const { 父母,孩子} = this.state;const { name } = this.props;返回 (<div className="boxed"><span>{name}</span><父开关childrenCount={children.length}parentSwitch={parent.value}onSelect={this.handleParentClick}/>{children.map(({ id, name, isEnabled }) => (<片段键={id}><span>{name}</span><ChildSwitch开关名称={id}选择={已启用}onSelect={this.setChildSwitchValue}/></片段>))}

);}}

For a setting page for an application, I have implemented a slider that has enabled(green) or disabled(red) state. And parent's settings are calculated based on the values of its children.

//Getting the switches configuration inside componnetDidMount something like this

var obj = [
  {
    parent_header_name: "parent1",
    children_info: [
      {
        child_switch_name: "child1",
        isEnabled: true
      },
      {
        child_switch_name: "child2",
        isEnabled: false
      }
    ]
  },
  {
    parent_header_name: "parent2",
    children_info: [
      {
        child_switch_name: "child3",
        isEnabled: true
      }
    ]
  },
  {
    parent_header_name: "parent3",
    children_info: [
      {
        child_switch_name: "child4",
        isEnabled: false
      }
    ]
  }
];

Now based on this value, I need to form a grouping of parent and children something like this:

Label(the value should be parent_header_name) : Parent Switch Component
Label for children(children_switch_name) : Child Switch Component

Also on change of individual children switches toggling I need to get the info of that switch something like this:

For Example, Changing parent1's child1's to disabled

[
  {
    parent_header_name: "parent1",
    children_info: [
      {
        child_switch_name: "child1",
        isEnabled: false
      }
    ]
  }
];

In case parent1 turned to enabled I need to get all its chidren value

[
  {
    parent_header_name: "parent1",
    children_info: [
      {
        child_switch_name: "child1",
        isEnabled: true
      },
      {
        child_switch_name: "child2",
        isEnabled: true
      }
    ]
  }
]

And when parents switch is toggled(when the parent is enabled, children will be enabled and when disabled children will be disabled;), I need to get the entire info of that parent

Also, I need to avoid toggling to "partial" state, the parent should only be enabled or disabled. "Partial" is only representational

For this, I am using react-multi-toggle for this toggle switch.

I have tried something like this: https://codesandbox.io/s/parent-child-switches-gxfx6

解决方案

You can refactor your Setting component to allow it to renders your switches name and value according to the data received from the API. I will suggest you add an id to each of your switches group, that will ease your work. Here is forked working sandbox. The code can be uptimzed to befit your usecase. The key changes are done in the Setting Component.

Setting Component Full code

import React, { Component, Fragment } from "react";
import isEqual from "lodash.isequal";

import ChildSwitch from "./ChildSwitch";
import ParentSwitch from "./ParentSwitch";
import { PARTIAL } from "./constant";

export default class Setting extends Component {
  state = {
    parent: {
      value:
        this.props.children.length > 1
          ? PARTIAL
          : this.props.children[0].isEnabled
    },
    children: this.props.children
  };

  componentDidMount() {
    this.setParentSwitchValue();
  }

  shouldComponentUpdate(nextProps, nextState) {
    return !isEqual(this.state, nextState);
  }

  setChildSwitchValue = (id, isEnabled) => {
    let clickedChild;
    this.setState(
      prevState => ({
        ...prevState,
        children: prevState.children.map(child => {
          if (child.id === id) {
            clickedChild = { ...child, isEnabled: isEnabled };
            return clickedChild;
          } else {
            return child;
          }
        })
      }),
      () => this.setParentSwitchValue(clickedChild)
    );
  };

  setParentSwitchValue = clickedChild => {
    const { children } = this.state;
    let parentVal = PARTIAL;

    if (children.every(({ isEnabled }) => isEnabled === true)) {
      parentVal = true;
    }
    if (children.every(({ isEnabled }) => isEnabled === false)) {
      parentVal = false;
    }

    this.setState(
      prevState => ({
        ...prevState,
        parent: {
          value: parentVal
        }
      }),
      () => {
        this.handleChange();
        if (clickedChild) {
          const changed = {
            parent: {
              name: this.props.name,
              value: parentVal
            },
            child: clickedChild
          };
          console.log("This is the changed child", changed);
        }
      }
    );
  };

  setChildrenValue = value => {
    this.setState(
      prevState => ({
        ...prevState,
        parent: {
          value
        },
        children: prevState.children.map(child => ({
          ...child,
          isEnabled: value
        }))
      }),
      this.handleChange
    );
  };

  handleChange = () => {
    const { id, onChange } = this.props;
    onChange(id, this.state);
  };

  handleParentClick = parentVal => {
    if (parentVal !== PARTIAL) {
      this.setChildrenValue(parentVal);
    }
  };

  render() {
    const { parent, children } = this.state;
    const { name } = this.props;
    return (
      <div className="boxed">
        <span>{name}</span>
        <ParentSwitch
          childrenCount={children.length}
          parentSwitch={parent.value}
          onSelect={this.handleParentClick}
        />
        {children.map(({ id, name, isEnabled }) => (
          <Fragment key={id}>
            <span>{name}</span>
            <ChildSwitch
              switchName={id}
              selected={isEnabled}
              onSelect={this.setChildSwitchValue}
            />
          </Fragment>
        ))}
      </div>
    );
  }
}

这篇关于根据对象数组形成组件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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