问题
I have a function which triggers children checkboxes once main checkbox is checked, and all these checkboxes are mapped from JSON. The main checkboxes (Highest level) and all of its children checkboxes (2nd level) under them are shown on click and its working great, what I am trying to display is the children of those children of the main checkboxes (3rd level) on clicking the 2nd level items.
Basically to show all three orders under each other on check, and add the 3rd order to my current code, so Options Group shows Options, and under Options is what I want to show, which are Option 1, Option 2, option 3 and so on..
The checkbox values are passed as props from Checkbox.js to Itemlist.js where the fetch/map happens.
(P.S. I have selection limit on each section in case anyone got confused about the selection process, which is not relevant to this question and can be ignored)
Main Snippet : https://codesandbox.io/embed/6jykwp3x6n?fontsize=14
The 3rd level targeted boxes for demonstration only: https://codesandbox.io/embed/o932z4yr6y?fontsize=14 ,
Checkbox.js
import React from "react";
import "./Checkbox.css";
class Checkboxes extends React.Component {
constructor(props) {
super(props);
this.state = {
currentData: 0,
limit: 2,
checked: false
};
}
selectData(id, event) {
let isSelected = event.currentTarget.checked;
if (isSelected) {
if (this.state.currentData < this.props.max) {
this.setState({ currentData: this.state.currentData + 1 });
} else {
event.preventDefault();
event.currentTarget.checked = false;
}
} else {
if (this.state.currentData >= this.props.min) {
this.setState({ currentData: this.state.currentData - 1 });
} else {
event.preventDefault();
event.currentTarget.checked = true;
}
}
}
render() {
const input2Checkboxes =
this.props.options &&
this.props.options.map(item => {
return (
<div className="inputGroup2">
{" "}
<div className="inputGroup">
<input
id={this.props.childk + (item.name || item.description)}
name="checkbox"
type="checkbox"
onChange={this.selectData.bind(
this,
this.props.childk + (item.name || item.description)
)}
/>
<label
htmlFor={this.props.childk + (item.name || item.description)}
>
{item.name || item.description}{" "}
</label>
</div>
</div>
);
});
return (
<form className="form">
<div>
{/** <h2>{this.props.title}</h2>*/}
<div className="inputGroup">
<input
id={this.props.childk + this.props.name}
name="checkbox"
type="checkbox"
checked={this.state.checked}
onChange={this.selectData.bind(
this,
this.props.childk + this.props.uniq
)}
onChange={() => {
this.setState({
checked: !this.state.checked,
currentData: 0
});
}}
/>
<label htmlFor={this.props.childk + this.props.name}>
{this.props.name}{" "}
</label>
</div>{" "}
{this.state.checked ? input2Checkboxes : undefined}
</div>
</form>
);
}
}
export default Checkboxes;
Itemlist.js Where the mapping function happen
...
const selectedItem =
selectedChild.children && selectedChild.children.length
? selectedChild.children[this.state.itemSelected]
: null;
...
<div>
{selectedItem &&
selectedItem.children &&
selectedItem.children.map((item, index) => (
<Checkboxes
key={index}
name={item.name || item.description}
myKey={index}
options={item.children}
childk={item.id}
max={item.max}
min={item.min}
/>
))}
</div>
...
回答1:
The issue is a recursive one. When an options group is displayed, the group checkbox and its options are displayed. When displaying the options, their type has to be taken into account.
- If the option is an
ingredient
, a simple checkbox can be displayed. - If it is a
group
, a new options group has to be displayed with its options, like discribed above.
This is what is missing in your code. Here is a working sandbox and here is how you can fix it:
in Checkbox.js:
const input2Checkboxes =
this.props.options &&
this.props.options.map((item, index) => {
// Is the option a 'group' or an 'ingredient'?
return item.type === "group" ? (
{/* It's a group so display its options recursively */}
<Checkboxes
key={index}
name={item.name || item.description}
options={item.children}
childk={this.props.childk}
max={item.max}
min={item.min}
/>
) : (
{/* It's an ingredient so display a simple checkbox */}
<div className="inputGroup2" key={item.name || item.description}>
{" "}
<div className="inputGroup">
<input
id={this.props.childk + (item.name || item.description)}
name="checkbox"
type="checkbox"
onChange={this.selectData.bind(
this,
this.props.childk + (item.name || item.description)
)}
/>
<label
htmlFor={this.props.childk + (item.name || item.description)}
>
{item.name || item.description}{" "}
</label>
</div>
</div>
);
});
来源:https://stackoverflow.com/questions/55131710/mapping-checkboxes-inside-checkboxes-reactjs