I have a bunch of checkbox-list requirements. I will explain in detail. I have a bunch of languages say:
var languages = ["English", "German", "French", "Spanish", "Mandarin", "Tamil"]
I have a parent component which has a form where I have four sections, Say:
class Page extends React.Component {
render() {
return (
<form>
<h1>CanSpeak</h1> <chkboxlist someProp="speak" />
<h1>CanSpeak</h1> <chkboxlist someProp="read" />
<h1>CanSpeak</h1> <chkboxlist someProp="write" />
<h1>CanSpeak</h1> <chkboxlist someProp="understand" />
<button
onClick={e => {
console.log("Need the various chkboxlist values here");
e.preventDefault();
}}
>
Save
</button>
</form>
);
}
}
I want the chkboxlist component to keep track of the list of selected languages in each section and make them available in the "Save" button click handler. I wish to keep track of the state changes (list of selected languages under each section) in the "Page" component.
I do not want to use redux or some such external state management.
Now what is the way to create this chkboxlist component such that the state changes can be tracked in the parent Page component ? Are there any existing components which will fit this requirement and is used widely in the react ecosystem without having to reinvent the wheel ?
As a result, the child components only update when the parent component's state changes with one of those functions. Directly mutating the props object is not allowed since this won't trigger any changes, and React doesn't notice the changes.
We can set Parent State from Children Component in ReactJs using the following approach. We will actually set the state of a parent in the parent component itself, but the children will be responsible for setting. We will create a function in parent to set the state with the given input.
No, it will not re-render. If you pass any props to the component from the parent component and you update that prop in children or that prop update in the parent component so both will re-render.
To update the parent state from the children component, either we can use additional dependencies like Redux or we can use this simple method of passing the state of the parent to the children and handling it accordingly.
I don't know if pulling in a seperate component would be really useful - as it's only a really tiny piece of functionality.
Working fiddle here: https://jsbin.com/tusakexire/edit?html,js,output
You could do something like:
class Chkboxlist extends React.Component {
constructor(props) {
super(props)
this.state = {}
props.values.map((v, i) => {
this.state[v] = false
})
}
onChange(key, value) {
this.setState({ [key]: value }, (state) => {
this.props.onChange(this.state)
})
}
render() {
return (
<div className="list-group-item form-group">
{this.props.values.map((value, i) => (
<div className="checkbox" key={i}>
<label>
<input
onChange={(e) => this.onChange(value, e.target.checked)}
type='checkbox'
value={this.state[value]}
/>
{value}
</label>
</div>
))}
</div>
)
}
}
class Page extends React.Component {
constructor(props) {
super(props)
this.state = {}
}
onChange(name, values) {
this.setState({ [name]: values })
}
render() {
const languages = ["English", "German", "French", "Spanish", "Mandarin", "Tamil"]
return (
<div className="container">
<div className="row">
<form className="form">
<div className="list-group col-xs-6">
<h4>Can Speak</h4>
<Chkboxlist
onChange={(values) => this.onChange('speak', values)}
values={languages}
/>
</div>
<div className="list-group col-xs-6">
<h4>Can Read</h4>
<Chkboxlist
onChange={(values) => this.onChange('read', values)}
values={languages}
/>
</div>
<div className="list-group col-xs-6">
<h4>Can Write</h4>
<Chkboxlist
onChange={(values) => this.onChange('write', values)}
values={languages}
/>
</div>
<div className="list-group col-xs-6">
<h4>Can Understand</h4>
<Chkboxlist
onChange={(values) => this.onChange('understand', values)}
values={languages}
/>
</div>
<button
className="btn btn-primary"
onClick={(e) => {
console.log(this.state);
e.preventDefault();
}}
>
Save
</button>
</form>
</div>
</div>
);
}
}
ReactDOM.render(<Page />, document.getElementById('app'))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With