以 parent 组件内的 object 的形式从所有 child 组件获取合并数据:React JS
Get consolidated data from all the child components in the form of an object inside a parent component : React JS
我正在为一个应用程序实现一个设置页面。对于每个设置,我都实现了一个启用(绿色)或禁用(红色)状态的滑块。但是 parent 的设置是只读的,是根据其 children.
的值计算的
Parent的设置推导如下:如果所有children都是红色,parent保持红色;如果全部都是绿色 parent 保持绿色;如果 at-least child 之一是绿色,那么 parent 保持灰色(待定)。
这些设置按如下方式分组:
Parent 特征 1 : (read-only-toggle)
Setting 1 (Toggle)
Setting 2 (Toggle)
Parent 特点二:(read-only-toggle)
Setting 1 (Toggle)
Setting 2 (Toggle)
最后还有一个按钮,它为我提供了所有 parent 和 children 的综合值。但到目前为止,我只能用一个 parent 和 2 children.
有人可以提供一种在一个地方获取所有设置的综合值的方法吗(就像配置了所有这些设置的超级 parent 组件)。
为此,我将 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>
</>
);
}
}
子设置
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}
/>
);
}
}
Parent 设置
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={() => {}}
/>
);
}
}
将您所有的状态放在一个 context hook 中。
const SettingsContext = createContext({state1, state2/* all your states in here*/);
然后你将把整个事情包装到这个上下文中:
<SettingsContext.Provider>
<App/>
</SettingsContext.Provider>
现在您可以访问任何 children、parents 等中的状态。但是我建议不要将 "disabled"、"enabled" 之类的东西存储为字符串,但是而是将状态存储为 { enabled: true, pending: false}
我建议您将 child 和 parent 分组在一个组件下。假设我们将其命名为 Settings
。然后,我们创建另一个组件,它将呈现一个设置列表和一个按钮。最后一个组件将保存所有设置的值。最后,每次 Setting Component Change
的值,我们更新列表。检查示例 working app here.
应用组件
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>
);
}
}
我正在为一个应用程序实现一个设置页面。对于每个设置,我都实现了一个启用(绿色)或禁用(红色)状态的滑块。但是 parent 的设置是只读的,是根据其 children.
的值计算的Parent的设置推导如下:如果所有children都是红色,parent保持红色;如果全部都是绿色 parent 保持绿色;如果 at-least child 之一是绿色,那么 parent 保持灰色(待定)。
这些设置按如下方式分组:
Parent 特征 1 : (read-only-toggle)
Setting 1 (Toggle)
Setting 2 (Toggle)
Parent 特点二:(read-only-toggle)
Setting 1 (Toggle)
Setting 2 (Toggle)
最后还有一个按钮,它为我提供了所有 parent 和 children 的综合值。但到目前为止,我只能用一个 parent 和 2 children.
有人可以提供一种在一个地方获取所有设置的综合值的方法吗(就像配置了所有这些设置的超级 parent 组件)。
为此,我将 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>
</>
);
}
}
子设置
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}
/>
);
}
}
Parent 设置
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={() => {}}
/>
);
}
}
将您所有的状态放在一个 context hook 中。
const SettingsContext = createContext({state1, state2/* all your states in here*/);
然后你将把整个事情包装到这个上下文中:
<SettingsContext.Provider>
<App/>
</SettingsContext.Provider>
现在您可以访问任何 children、parents 等中的状态。但是我建议不要将 "disabled"、"enabled" 之类的东西存储为字符串,但是而是将状态存储为 { enabled: true, pending: false}
我建议您将 child 和 parent 分组在一个组件下。假设我们将其命名为 Settings
。然后,我们创建另一个组件,它将呈现一个设置列表和一个按钮。最后一个组件将保存所有设置的值。最后,每次 Setting Component Change
的值,我们更新列表。检查示例 working app here.
应用组件
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>
);
}
}