Reputation: 9662
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
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);
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={() => {}}
/>
);
}
}
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}
/>
);
}
}
Upvotes: 0
Views: 79
Reputation: 88
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.
Upvotes: 2
Reputation: 595
setChildSwitchValue = value => {
this.setState({ value });
};
this adds {value: value} to the state and results in this state:
{parentVal: "", switch1Val: "", switch2Val: "", switch3Val: "", value: "enabled"}
Upvotes: 1