Reputation: 9645
Suppose I have a settings screen on my React app, with three settings
What's the best way to handle all the onchange events from all these controls? Here's what I have at the minute
import React from 'react';
import Modal from 'react-bootstrap-modal';
export default class Settings extends React.Component {
constructor (props) {
super(props)
this.state = {
open: false
}
this.handleThingieChange = this.handleThingieChange.bind(this);
this.handleDoohickeyChange = this.handleDoohickeyChange.bind(this);
this.handleGizmoChange = this.handleGizmoChange.bind(this);
}
handleThingieChange(e) {
this.props.onThingieChange(e.target.value)
}
handleDoohickeyChange(e) {
this.props.onDoohickeyChange(e.target.value);
}
handleGizmoChange(e) {
this.props.onGizmoChange(e.target.checked);
}
render() {
return (
<div>
<label>enable thingie</label>
<input type="checkbox" checked={this.props.thingie} onChange={this.handleThingieChange} />
<label>use doohickey</label>
<input type="checkbox" checked={this.props.doohickey} onChange={this.handleDoohickeyChange} />
<label>activate gizmo</label>
<input type="checkbox" checked={this.props.gizmo} onChange={this.handleGizmoChange} />
</div>
)
}
}
And in my <App>
component:
thingieChange(thingie){
this.setState({ thingie: thingie })
}
doohickeyChange(doohickey){
this.setState({ doohickey: doohickey })
}
gizmoChange(gizmo){
this.setState({ gizmo: gizmo })
}
// render method is most important
// render method returns JSX template
render() {
return (
<form>
<h2>headerooney</h2>
<Settings
onThingieChange={this.thingieChange.bind(this)}
onDoohickeyChange={this.doohickeyChange.bind(this)}
onGizmoChange={this.gizmoChange.bind(this)} />
</form>
);
}
My app could potentially have 20 or 30 settings, it seems like there must be a better way to do this than by repeating this pattern 20-30 times?
I'm new to react, if I was building this with jquery I'd do something like this:
<div>
<label>enable thingie</label>
<input type="checkbox" data-property='thingie' />
<label>use doohickey</label>
<input type="checkbox" data-property='doohickey' />
<label>activate gizmo</label>
<input type="checkbox" data-property='gizmo' />
</div>
with a generic click handler like this
$(function(){
$.each(options, function(k, v) {
$("[data-property='" + k + "']")[0].checked = v;
});
$(document).on("click", "input[type='checkbox']", function(){
var propertyName = $(this).data("property");
options[propertyName] = $(this)[0].checked;
console.log(options);
})
});
How do I do something equivalent in react? I don't want to spend two hours writing a handler function for every single setting
Upvotes: 1
Views: 322
Reputation: 1845
If all of your controls are just checkboxes then why not create a single component for a setting and then have a Settings component that lists them all.
You could provide the name of the setting as a property for the component so that it knows what it was updating. You could pass a function from the Settings component to the Setting component that provided the means to update state.
One more complex option for addressing this would be to use Redux but it is probably not necessary for something this straightforward (although it would provide plenty of benefit in terms of simplifying testing, etc).
I would suggest though that as soon as you seen any kind of repeating pattern that you try to abstract it to a reusable component - it will definitely save you time in the long run.
Upvotes: 1