问题
I need a solution for radio buttons, but the options array which is the main array is outside the class component. In this case, I will get OPTIONS array items through props but not hardcoded. How is it possible for me to
Pass props outside class component
Make OPTIONS state object and then pass it to checkboxes, which is inside state.
import React, { Component } from "react"; import Checkbox from "./Checkbox"; const OPTIONS = ["One", "Two", "Three"]; class App extends Component { state = { checkboxes: OPTIONS.reduce( (options, option) => ({ ...options, [option]: false }), {} ) }; selectAllCheckboxes = isSelected => { Object.keys(this.state.checkboxes).forEach(checkbox => { // BONUS: Can you explain why we pass updater function to setState instead of an object? this.setState(prevState => ({ checkboxes: { ...prevState.checkboxes, [checkbox]: isSelected } })); }); }; selectAll = () => this.selectAllCheckboxes(true); deselectAll = () => this.selectAllCheckboxes(false); handleCheckboxChange = changeEvent => { const { name } = changeEvent.target; this.setState(prevState => ({ checkboxes: { ...prevState.checkboxes, [name]: !prevState.checkboxes[name] } })); }; handleFormSubmit = formSubmitEvent => { formSubmitEvent.preventDefault(); Object.keys(this.state.checkboxes) .filter(checkbox => this.state.checkboxes[checkbox]) .forEach(checkbox => { console.log(checkbox, "is selected."); }); }; createCheckbox = option => ( <Checkbox label={option} isSelected={this.state.checkboxes[option]} onCheckboxChange={this.handleCheckboxChange} key={option} /> ); createCheckboxes = () => OPTIONS.map(this.createCheckbox); render() { return ( <div className="container"> <div className="row mt-5"> <div className="col-sm-12"> <form onSubmit={this.handleFormSubmit}> {this.createCheckboxes()} <div className="form-group mt-2"> <button type="button" className="btn btn-outline-primary mr-2" onClick={this.selectAll} > Select All </button> <button type="button" className="btn btn-outline-primary mr-2" onClick={this.deselectAll} > Deselect All </button> <button type="submit" className="btn btn-primary"> Save </button> </div> </form> </div> </div> </div> ); } } export default App;
回答1:
You can invoke options directly in state and then use constructor to map them to checkboxes. hope this helps.
import React, { Component } from "react";
import Checkbox from "./Checkbox";
class App extends Component {
constructor(props){
super(props)
this.state.checkboxes = this.state.options.reduce(
(options, option) => ({
...options,
[option]: false
}),
{}
)
}
state = {
options: ["One", "Two", "Three"]
};
selectAllCheckboxes = isSelected => {
Object.keys(this.state.checkboxes).forEach(checkbox => {
// BONUS: Can you explain why we pass updater function to setState instead of an object?
this.setState(prevState => ({
checkboxes: {
...prevState.checkboxes,
[checkbox]: isSelected
}
}));
});
};
selectAll = () => this.selectAllCheckboxes(true);
deselectAll = () => this.selectAllCheckboxes(false);
handleCheckboxChange = changeEvent => {
const { name } = changeEvent.target;
this.setState(prevState => ({
checkboxes: {
...prevState.checkboxes,
[name]: !prevState.checkboxes[name]
}
}));
};
handleFormSubmit = formSubmitEvent => {
formSubmitEvent.preventDefault();
Object.keys(this.state.checkboxes)
.filter(checkbox => this.state.checkboxes[checkbox])
.forEach(checkbox => {
console.log(checkbox, "is selected.");
});
};
createCheckbox = option => (
<Checkbox
label={option}
isSelected={this.state.checkboxes[option]}
onCheckboxChange={this.handleCheckboxChange}
key={option}
/>
);
createCheckboxes = () => this.state.options.map(this.createCheckbox);
render() {
return (
<div className="container">
<div className="row mt-5">
<div className="col-sm-12">
<form onSubmit={this.handleFormSubmit}>
{this.createCheckboxes()}
<div className="form-group mt-2">
<button
type="button"
className="btn btn-outline-primary mr-2"
onClick={this.selectAll}
>
Select All
</button>
<button
type="button"
className="btn btn-outline-primary mr-2"
onClick={this.deselectAll}
>
Deselect All
</button>
<button type="submit" className="btn btn-primary">
Save
</button>
</div>
</form>
</div>
</div>
</div>
);
}
}
export default App;
来源:https://stackoverflow.com/questions/62849796/how-to-create-an-array-outside-class-component-or-reference-state-sibling-to-nex