I have a react component for a checkbox that is used in multiple components.
const Checkbox = (props) => {
return (
<Col>
<div className="switch">
<input id={props.value} type="checkbox" value={props.value} className="visually-hidden" onChange={props.handleChange}/>
<label htmlFor={props.value} className="switch-label checkbox-label text-center">{props.label}</label>
</div>
</Col>
)
}
export default Checkbox
I want to have a single function that handles the change from this component but work out the parent component that called it so I can update the correct value in my state.
For example, I have an Attendees component that uses my checkbox component:
export default class Attendees extends Component {
state = {
attendees: [
{id: 1, value: 500, label: "0 - 500", checked: false},
{id: 2, value: 1500, label: "500 - 1.5k", checked: false},
{id: 2, value: 5000, label: "1.5k - 5k", checked: false},
{id: 2, value: 10000, label: "5k - 10k", checked: false},
{id: 2, value: 25000, label: "10k - 25k", checked: false},
{id: 2, value: 50000, label: "25k - 50k", checked: false},
{id: 2, value: 1000000, label: "50k+", checked: false},
]
}
render() {
return (
<div>
<Row>
<Col>
<h4 className="ui centered question-header text-center">HOW MANY ATTENDEES DO YOU EXPECT?</h4>
</Col>
</Row>
<Row>
{
this.state.attendees.map((number) => {
return (<Checkbox name="attendees" key={number.value}
handleChange={this.props.handleChange} {...number} />)
})
}
</Row>
</div>
)
}
}
When my handleChange function gets fired I want to know if it came from the attendees component so I can update my attendee’s value in my state, currently I have this as my handleChange function which only updates the event_format on my state. Is this possible?
constructor() {
super();
this.state = {
event_format: [],
attendees: 0,
}
this.handleCheckboxChange = this.handleCheckboxChange.bind(this);
}
handleCheckboxChange(event) {
const target = event.target;
let value = target.value;
let eventFormatsCopy = this.state.event_format;
if (target.checked) {
eventFormatsCopy.push(value)
this.setState({
event_format: eventFormatsCopy
})
} else {
const index = eventFormatsCopy.indexOf(value)
eventFormatsCopy.splice(index, 1);
this.setState({
event_format: eventFormatsCopy
})
}
console.log(this.state)
}
The React way would involve passing props down each component, as an alternative (quicker) way you could use a distinct attribute on the parent element you can then use to back-reference from the
current
/target
node from the event e.g.Then you can traverse the DOM back up to detect if that particular ID is part of the ancestry. For illustration, if you are using jQuery as an example:
If you have many different scenarios and you need something a bit more flexible, maybe a custom attribute with a type would be better e.g.
data-component="attendees"
.I realize this has already been answered, but the accepted answer is A Bad Idea™ in my opinion, so I offer these simple alternatives.
1. Pass a different handler:
Or if you really need to use a single handler for whatever reason, you can…
2. Use the input’s name:
If you pass the
name
prop through to the input you can testtarget.name
in your change handler: