根据对象数组形成组件 [英] Forming the components based on the array of objects
问题描述
对于应用程序的设置页面,我实现了一个启用(绿色)或禁用(红色)状态的滑块.并且父级的设置是根据其子级的值计算的.
//获取componnetDidMount里面的开关配置是这样的var obj = [{parent_header_name: "parent1",儿童信息:[{child_switch_name: "child1",已启用:真},{child_switch_name: "child2",已启用:假}]},{parent_header_name: "parent2",儿童信息:[{child_switch_name: "child3",已启用:真}]},{parent_header_name: "parent3",儿童信息:[{child_switch_name: "child4",已启用:假}]}];
现在基于这个值,我需要像这样形成一个父子组:
Label(value 应该是 parent_header_name) : Parent Switch Component儿童标签(children_switch_name):子开关组件
此外,在更改单个孩子的开关切换时,我需要获取该开关的信息,如下所示:
例如,将 parent1 的 child1 更改为禁用
<预><代码>[{parent_header_name: "parent1",儿童信息:[{child_switch_name: "child1",已启用:假}]}];如果 parent1 已启用,我需要获取其所有 chidren 值
<预><代码>[{parent_header_name: "parent1",儿童信息:[{child_switch_name: "child1",已启用:真},{child_switch_name: "child2",已启用:真}]}]当父母开关被切换时(当父母被启用时,孩子将被启用,当被禁用的孩子将被禁用;),我需要获得该父母的完整信息
此外,我需要避免切换到部分"状态,只应启用或禁用父级.部分"只是代表性的
为此,我为此切换开关使用了 react-multi-toggle.
我尝试过这样的事情:https://codesandbox.io/s/父子开关-gxfx6
您可以重构您的 Setting 组件
以允许它根据呈现您的开关名称和值
从 API 接收的数据.我建议您为每个 switches group
添加一个 id,这将简化您的工作.这里是分叉的工作沙箱.可以优化代码以适合您的用例.关键更改在 Setting Component
中完成.
设置组件完整代码
import React, { Component, Fragment } from "react";从lodash.isequal"导入 isEqual;从./ChildSwitch"导入 ChildSwitch;从./ParentSwitch"导入ParentSwitch;从./constant"导入{部分};导出默认类设置扩展组件{状态 = {父母:{价值:this.props.children.length >1?部分的: this.props.children[0].isEnabled},儿童:this.props.children};componentDidMount() {this.setParentSwitchValue();}shouldComponentUpdate(nextProps, nextState) {返回 !isEqual(this.state, nextState);}setChildSwitchValue = (id, isEnabled) =>{让 clickedChild;这个.setState(上一个状态 =>({...prevState,儿童:prevState.children.map(child => {如果(child.id === id){clickedChild = { ...child, isEnabled: isEnabled };返回 clickedChild;} 别的 {返回孩子;}})}),() =>this.setParentSwitchValue(clickedChild));};setParentSwitchValue = clickedChild =>{const { children } = this.state;让 parentVal = PARTIAL;if (children.every(({ isEnabled }) => isEnabled === true)) {parentVal = 真;}if (children.every(({ isEnabled }) => isEnabled === false)) {parentVal = 假;}这个.setState(上一个状态 =>({...prevState,父母:{值:parentVal}}),() =>{this.handleChange();如果(clickedChild){常量更改 = {父母:{名称:this.props.name,值:parentVal},孩子:clickedChild};console.log("这是改变的孩子", changed);}});};setChildrenValue = 值 =>{这个.setState(上一个状态 =>({...prevState,父母:{价值},儿童:prevState.children.map(child => ({...孩子,isEnabled:值}))}),this.handleChange);};handleChange = () =>{const { id, onChange } = this.props;onChange(id, this.state);};handleParentClick = parentVal =>{如果(parentVal !== 部分){this.setChildrenValue(parentVal);}};使成为() {const { 父母,孩子} = this.state;const { name } = this.props;返回 (<div className="boxed"><span>{name}</span><父开关childrenCount={children.length}parentSwitch={parent.value}onSelect={this.handleParentClick}/>{children.map(({ id, name, isEnabled }) => (<片段键={id}><span>{name}</span><ChildSwitch开关名称={id}选择={已启用}onSelect={this.setChildSwitchValue}/></片段>))}
);}}
For a setting page for an application, I have implemented a slider that has enabled(green) or disabled(red) state. And parent's settings are calculated based on the values of its children.
//Getting the switches configuration inside componnetDidMount something like this
var obj = [
{
parent_header_name: "parent1",
children_info: [
{
child_switch_name: "child1",
isEnabled: true
},
{
child_switch_name: "child2",
isEnabled: false
}
]
},
{
parent_header_name: "parent2",
children_info: [
{
child_switch_name: "child3",
isEnabled: true
}
]
},
{
parent_header_name: "parent3",
children_info: [
{
child_switch_name: "child4",
isEnabled: false
}
]
}
];
Now based on this value, I need to form a grouping of parent and children something like this:
Label(the value should be parent_header_name) : Parent Switch Component
Label for children(children_switch_name) : Child Switch Component
Also on change of individual children switches toggling I need to get the info of that switch something like this:
For Example, Changing parent1's child1's to disabled
[
{
parent_header_name: "parent1",
children_info: [
{
child_switch_name: "child1",
isEnabled: false
}
]
}
];
In case parent1 turned to enabled I need to get all its chidren value
[
{
parent_header_name: "parent1",
children_info: [
{
child_switch_name: "child1",
isEnabled: true
},
{
child_switch_name: "child2",
isEnabled: true
}
]
}
]
And when parents switch is toggled(when the parent is enabled, children will be enabled and when disabled children will be disabled;), I need to get the entire info of that parent
Also, I need to avoid toggling to "partial" state, the parent should only be enabled or disabled. "Partial" is only representational
For this, I am using react-multi-toggle for this toggle switch.
I have tried something like this: https://codesandbox.io/s/parent-child-switches-gxfx6
You can refactor your Setting component
to allow it to renders your switches name and value according
to the data received from the API. I will suggest you add an id to each of your switches group
, that will ease your work. Here is forked working sandbox. The code can be uptimzed to befit your usecase. The key changes are done in the Setting Component
.
Setting Component Full code
import React, { Component, Fragment } from "react";
import isEqual from "lodash.isequal";
import ChildSwitch from "./ChildSwitch";
import ParentSwitch from "./ParentSwitch";
import { PARTIAL } from "./constant";
export default class Setting extends Component {
state = {
parent: {
value:
this.props.children.length > 1
? PARTIAL
: this.props.children[0].isEnabled
},
children: this.props.children
};
componentDidMount() {
this.setParentSwitchValue();
}
shouldComponentUpdate(nextProps, nextState) {
return !isEqual(this.state, nextState);
}
setChildSwitchValue = (id, isEnabled) => {
let clickedChild;
this.setState(
prevState => ({
...prevState,
children: prevState.children.map(child => {
if (child.id === id) {
clickedChild = { ...child, isEnabled: isEnabled };
return clickedChild;
} else {
return child;
}
})
}),
() => this.setParentSwitchValue(clickedChild)
);
};
setParentSwitchValue = clickedChild => {
const { children } = this.state;
let parentVal = PARTIAL;
if (children.every(({ isEnabled }) => isEnabled === true)) {
parentVal = true;
}
if (children.every(({ isEnabled }) => isEnabled === false)) {
parentVal = false;
}
this.setState(
prevState => ({
...prevState,
parent: {
value: parentVal
}
}),
() => {
this.handleChange();
if (clickedChild) {
const changed = {
parent: {
name: this.props.name,
value: parentVal
},
child: clickedChild
};
console.log("This is the changed child", changed);
}
}
);
};
setChildrenValue = value => {
this.setState(
prevState => ({
...prevState,
parent: {
value
},
children: prevState.children.map(child => ({
...child,
isEnabled: value
}))
}),
this.handleChange
);
};
handleChange = () => {
const { id, onChange } = this.props;
onChange(id, this.state);
};
handleParentClick = parentVal => {
if (parentVal !== PARTIAL) {
this.setChildrenValue(parentVal);
}
};
render() {
const { parent, children } = this.state;
const { name } = this.props;
return (
<div className="boxed">
<span>{name}</span>
<ParentSwitch
childrenCount={children.length}
parentSwitch={parent.value}
onSelect={this.handleParentClick}
/>
{children.map(({ id, name, isEnabled }) => (
<Fragment key={id}>
<span>{name}</span>
<ChildSwitch
switchName={id}
selected={isEnabled}
onSelect={this.setChildSwitchValue}
/>
</Fragment>
))}
</div>
);
}
}
这篇关于根据对象数组形成组件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!