繁体   English   中英

以父组件内对象的形式从所有子组件中获取合并数据:React JS

[英]Get consolidated data from all the child components in the form of an object inside a parent component : React JS

我正在为应用程序实现设置页面。 对于每个设置,我都实现了一个启用(绿色)或禁用(红色)状态的滑块。 但是父级的设置是只读的,是根据其子级的值计算得出的。

父级的设置如下:如果所有子代均为红色,则父代保持红色;否则,父代保持红色。 如果全部为绿色,则父母保持绿色;否则,父母保持绿色。 如果孩子的至少一位是绿色的,则父母保持灰色(待定)。

这些设置分为以下几类:

父功能1 :(只读切换)

 Setting 1   (Toggle)

 Setting 2   (Toggle)

父功能2 :(只读切换)

Setting 1   (Toggle)

Setting 2   (Toggle)

最后还有一个按钮,它为我提供了所有父母和孩子的合并值。 但是到目前为止,我只能与一位父母和两个孩子一起做。

有人可以提供一种在一个地方获取所有设置的合并值的方法的帮助吗(就像配置了所有这些设置的超级父组件一样)。

为此,我为此开关使用了react-multi-toggle。

帮助将不胜感激。

代码沙箱: https//codesandbox.io/s/react-multi-toggle-solution-perfect-v9bi5

应用


import React from "react";
import ChildSwitch from "./ChildSwitch";
import ParentSwitch from "./ParentSwitch";

export default class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      parentVal: "disabled",
      switch1Val: "enabled",
      switch2Val: "disabled"
    };
  }

  componentDidMount() {
    this.setParentSwitchValue();
  }

  onGetChildSwitchValues = () => {
    console.log(this.state);
  };

  setChildSwitchValue = (whichSwitch, selected) => {
    this.setState(
      prevState => ({ ...prevState, [whichSwitch]: selected }),
      this.setParentSwitchValue
    );
  };

  setParentSwitchValue = () => {
    const { switch1Val, switch2Val } = this.state;
    const switchStates = [switch1Val, switch2Val];
    let parent = "pending";
    if (switchStates.every(val => val === "enabled")) {
      parent = "enabled";
    }
    if (switchStates.every(val => val === "disabled")) {
      parent = "disabled";
    }
    this.setState(prevState => ({ ...prevState, parentVal: parent }));
  };

  render() {
    const { parentVal, switch1Val, switch2Val } = this.state;
    return (
      <>
        <div className="boxed">
          Parent Setting 1 :{" "}
          <ParentSwitch
            parentSwitch={parentVal}
            onSelect={this.setParentSwitchValue}
          />
          Setting 1:
          <ChildSwitch
            switchName={"switch1Val"}
            selected={switch1Val}
            onSelect={this.setChildSwitchValue}
          />
          Setting 2:
          <ChildSwitch
            switchName={"switch2Val"}
            selected={switch2Val}
            onSelect={this.setChildSwitchValue}
          />
        </div>
        <button onClick={this.onGetChildSwitchValues}>Get All Values</button>
      </>
    );
  }
}

ChildSetting


import MultiToggle from "react-multi-toggle";
import React from "react";

export default class ChildSwitch extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      options: [
        {
          displayName: "Disabled",
          value: "disabled"
        },
        {
          displayName: "Enabled",
          value: "enabled"
        }
      ]
    };
  }

  onSelectOption = selected => {
    this.props.onSelect(this.props.switchName, selected);
  };

  render() {
    const { options } = this.state;
    const { selected } = this.props;
    return (
      <MultiToggle
        options={options}
        selectedOption={selected}
        onSelectOption={this.onSelectOption}
      />
    );
  }
}

家长设置


import MultiToggle from "react-multi-toggle";
import React from "react";
import "react-multi-toggle/style.css";

export default class ParentSwitch extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      options: [
        {
          displayName: "Disabled",
          value: "disabled"
        },
        {
          displayName: "Pending",
          value: "pending"
        },
        {
          displayName: "Enabled",
          value: "enabled"
        }
      ]
    };
  }

  render() {
    const { options } = this.state;
    return (
      <MultiToggle
        options={options}
        selectedOption={this.props.parentSwitch}
        onSelectOption={() => {}}
      />
    );
  }
}



我建议您将孩子和父母归为一个组成部分。 假设我们将其命名为Settings 然后,我们创建另一个组件,该组件将呈现“设置”列表和一个按钮。 最后一个组件将保存所有设置的值。 最后,每次“ Setting Component Change的值时,我们都会更新列表。 在此处签出示例工作应用程序

应用组件

export default class App extends PureComponent {
  state = {};

  onSettingChange = (settingId, setting) => {
    this.setState(prevState => ({
      ...prevState,
      [settingId]: setting
    }));
  };

  onGetSettingValues = () => {
    console.log(this.state);
  };

  render() {
    return (
      <Fragment>
        <Setting id="setting1" onChange={this.onSettingChange} />
        <Setting id="setting2" onChange={this.onSettingChange} />
        <button onClick={this.onGetSettingValues}>Get All Values</button>
      </Fragment>
    );
  }
}

设定元件

import React, { PureComponent, Fragment } from "react";
import ChildSwitch from "./ChildSwitch";
import ParentSwitch from "./ParentSwitch";

export default class Setting extends PureComponent {
  state = {
    parentVal: "disabled",
    switch1Val: "enabled",
    switch2Val: "disabled"
  };

  componentDidMount() {
    this.setParentSwitchValue();
  }

  setChildSwitchValue = (whichSwitch, selected) => {
    this.setState(
      prevState => ({ ...prevState, [whichSwitch]: selected }),
      this.setParentSwitchValue
    );
  };

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

  setParentSwitchValue = () => {
    const { switch1Val, switch2Val } = this.state;
    const switchStates = [switch1Val, switch2Val];
    let parent = "pending";
    if (switchStates.every(val => val === "enabled")) {
      parent = "enabled";
    }
    if (switchStates.every(val => val === "disabled")) {
      parent = "disabled";
    }

    this.setState(
      prevState => ({ ...prevState, parentVal: parent }),
      this.handleChange
    );
  };

  render() {
    const { parentVal, switch1Val, switch2Val } = this.state;
    return (
      <Fragment>
        <div className="boxed">
          Parent Setting 1
          <ParentSwitch
            parentSwitch={parentVal}
            onSelect={this.setParentSwitchValue}
          />
          Setting 1:
          <ChildSwitch
            switchName={"switch1Val"}
            selected={switch1Val}
            onSelect={this.setChildSwitchValue}
          />
          Setting 2:
          <ChildSwitch
            switchName={"switch2Val"}
            selected={switch2Val}
            onSelect={this.setChildSwitchValue}
          />
        </div>
      </Fragment>
    );
  }
}

将所有状态放入单个上下文挂钩

const SettingsContext = createContext({state1, state2/* all your states in here*/);

然后,您将整个内容包装到该上下文中,如下所示:

<SettingsContext.Provider>
  <App/>
</SettingsContext.Provider>

现在您可以访问任何孩子,父母等中的状态。但是我建议不要将“ disabled”,“ enabled”之类的内容存储为字符串,而应将状态存储为{ enabled: true, pending: false}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM