Skip to content Skip to sidebar Skip to footer

Get Consolidated Data From All The Child Components In The Form Of An Object Inside A Parent Component : React Js

I am implementing a setting page for an application. For each setting I have implemented a slider that has enabled(green) or disabled(red) state. But parent's settings is read only

Solution 1:

I will suggest that you group your child and parent under one component. Let say we name it Settings. Then, we create another component that will render a list of Settings and a button. This last component will hold the values of all Settings. Finally, each time the value of a Setting Component Change, we update the list. Checkout a sample working app here.

App Component

exportdefaultclassAppextendsPureComponent {
  state = {};

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

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

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

Setting Component

importReact, { PureComponent, Fragment } from"react";
importChildSwitchfrom"./ChildSwitch";
importParentSwitchfrom"./ParentSwitch";

exportdefaultclassSettingextendsPureComponent {
  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><divclassName="boxed">
          Parent Setting 1
          <ParentSwitchparentSwitch={parentVal}onSelect={this.setParentSwitchValue}
          />
          Setting 1:
          <ChildSwitchswitchName={"switch1Val"}
            selected={switch1Val}onSelect={this.setChildSwitchValue}
          />
          Setting 2:
          <ChildSwitchswitchName={"switch2Val"}
            selected={switch2Val}onSelect={this.setChildSwitchValue}
          /></div></Fragment>
    );
  }
}

Solution 2:

Put all your states into a single context hook.

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

You'll then wrap the whole thing into this context as such:

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

Now you can access the state in any of the children, parents etc. I suggest however not storing things like "disabled", "enabled" as strings, but rather store states as { enabled: true, pending: false}

Post a Comment for "Get Consolidated Data From All The Child Components In The Form Of An Object Inside A Parent Component : React Js"