Reputation: 6338
What is the proper way to declare event handler from container to the presentation widget so that I can access other props in the event handler function?
class ApplicationWidget extends Component {
componentDidMount() {
this.props.handle_onload.call(this);
}
render() {
return (
<div onClick={this.props.handle_click}>
<Header />
<Content />
</div>
);
}
}
export default connect(
state => {
return {foo: state.foo};
},
dispatch => {
return {
handle_click() {
console.log(this)
},
handle_onload() {
jQuery.get({
accepts: 'application/json',
success: (data) => dispatch(the_action_creator(data)),
url: `/initialize`
});
}
};
}
)(ApplicationWidget);
Currently the this.props.handle_click
event handler logs undefined
whenever the click event happens. If I want access to this.props.foo
, what is the right way of doing it? My current implementation is
<div onClick={this.props.handle_click.bind(this)}>
in the render()
method and it works as intended however according to the linter this doesn't look like a good practice. The following code doesn't seem to work after the container (generated by the connect
function) is updated (the binding is reseted to undefined
for some reason)
constructor(props) {
super(props);
this.props.handle_click = this.props.handle_click.bind(this)
}
So what is the right way to do this? Or am I doing this whole thing wrong?
Upvotes: 1
Views: 553
Reputation: 20256
The prop handle_click
is just a function that is passed to the component by reference, so it doesn't “know” anything about the scope (this) of the component. You can change that using the bind method that is available to all functions, like this:
class ApplicationWidget extends Component {
componentDidMount() {
this.props.handle_onload.call(this);
}
render() {
return (
<div onClick={this.props.handle_click.bind(this)}>
<Header />
<Content />
</div>
);
}
}
To optimize this and prevent your linter from complaining, you can bind it in the constructor like this:
class ApplicationWidget extends Component {
constructor(props) {
super(props);
this.handle_click = props.handle_click.bind(this);
}
componentDidMount() {
this.props.handle_onload.call(this);
}
render() {
return (
<div onClick={this.handle_click}>
<Header />
<Content />
</div>
);
}
}
So you almost got it right, but I wouldn't modify the props in the constructor, just add another method to the class.
Upvotes: 2