Compute the parents state based on the data of the child components: ReactJS

落爺英雄遲暮 提交于 2019-12-11 14:27:59

问题


I am trying to implement a settings page where I have a global settings and some kind of child settings(in form of a slider).

I have the following scenarios:

1)When all of the child settings is on , then parents switch state should be turned on state

2)When any of the child settings is off, then parents switch state should be switched to pending

3)When all of the child settings is off, then parents switch state should be switched to off state

4) Also On click of button, I need to get the current state of all the child components.

Have tried the following approach but it does not seem like working. For this , I am using react-multi-toggle for this toggle switch.

I am able to get the state whenever the you do toggling inside, but it is not propagating to parent

Can someone help here ?

Code Sandbox Link : https://codesandbox.io/s/react-multi-toggle-r5dpi

App.tsx

import React from "react";
import ReactDOM from "react-dom";
import ChildSwitch from "./ChildSwitch";
import ParentSwitch from "./ParentSwitch";
import "./styles.css";

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

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

  setChildSwitchValue = value => {
    this.setState({ value });
  };

  setParentSwitchValue = value => {
    this.setState({ value });
  };

  render() {
    const { parentVal, switch1Val, switch2Val, switch3Val } = this.state;
    return (
      <>
        Parent Switch :{" "}
        <ParentSwitch
          parentSwitch={parentVal}
          onSelect={this.setParentSwitchValue}
        />
        Child Switches :
        <ChildSwitch
          childSwitch={switch1Val}
          onSelect={this.setChildSwitchValue}
        />
        <ChildSwitch
          childSwitch={switch2Val}
          onSelect={this.setChildSwitchValue}
        />
        <ChildSwitch
          childSwitch={switch3Val}
          onSelect={this.setChildSwitchValue}
        />
        <button onClick={this.onGetChildSwitchValues}>Get Child Values</button>
      </>
    );
  }
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);


Parent Switch


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",
          optionClass: "red"
        },
        {
          displayName: "Pending",
          value: "pending",
          optionClass: "grey"
        },
        {
          displayName: "Enabled",
          value: "enabled",
          optionClass: "green"
        }
      ],
      selected: "pending"
    };
  }

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


ChildSwitch


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",
          optionClass: "red"
        },
        {
          displayName: "Enabled",
          value: "enabled",
          optionClass: "green"
        }
      ],
      selected: "disabled"
    };
  }

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

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





回答1:


I got you started with fixing your issue:

https://codesandbox.io/s/react-multi-toggle-5hvs1

The problems were... child information cannot propagate up to parent in React unless you have a single source of truth in your application either by using tools like Redux or just the local storage, which I don't advice.

So in that case, your child components need to be controlled ones. Parent should hold their state if they want to be aware of their children...

And from there you can do your comparisons for parent toggle all on or off or whatever.

Good luck.




回答2:


setChildSwitchValue = value => {
    this.setState({ value });
};

this adds {value: value} to the state and results in this state:

{parentVal: "", switch1Val: "", switch2Val: "", switch3Val: "", value: "enabled"}


来源:https://stackoverflow.com/questions/57529332/compute-the-parents-state-based-on-the-data-of-the-child-components-reactjs

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!