-
Star
(115)
You must be signed in to star a gist -
Fork
(20)
You must be signed in to fork a gist
-
-
Save Restuta/e400a555ba24daa396cc to your computer and use it in GitHub Desktop.
/* Sometimes it's pretty easy to run ito troubles with React ES6 components. | |
Consider the following code: */ | |
class EventStub extends Component { | |
componentDidMount() { | |
window.addEventListener('resize', this.onResize.bind(this)); //notice .bind | |
} | |
componentWillUnmount() { | |
window.removeEventListener('resize', this.onResize.bind(this)); | |
} | |
onResize() { | |
this.setState({width: this.div.offsetWidth}); | |
} | |
render() { return null; } | |
} | |
/* As a result EventListener won't be removed since A new function reference is created after .bind() is called. | |
(more http://stackoverflow.com/questions/11565471/removing-event-listener-which-was-added-with-bind | |
and http://alexfedoseev.com/post/65/react-event-handlers-and-context-binding). | |
Obviously this is not React's fault, it's how DOM works, but it's super easy to make a mistake. ESLint rule anyone? | |
What about solutions? Pretty straightforward one is to create bound funciton only once in constructor, | |
assign to internal prop and then use it:*/ | |
this.bound_onResize = this.onResize(bind); | |
//or replace the funtion with the bound one that allows to use same funtion: | |
this.onResize = this.onResize.bind(this); | |
//another options is to use arrow funciton on a class level so it'll capture "this" automatically, | |
//but this is as of Jan 2016 Stage 2 ES2016 (ES7) proposal and requires "babel experimental" flag | |
export class MyComponent extends Component { | |
onResize = () => this.onResize() | |
} |
Great!! Thank you mate! Saved me!
Thank you!
Thank you very much!
thanks for explaination
Thanks for this! 👍 🎉
Thanks for this! 👍
You can get this for free with arrow functions (https://medium.freecodecamp.org/react-binding-patterns-5-approaches-for-handling-this-92c651b5af56)
Thank you very much
Very useful, much appreciated.
Thanks 👍
I was also bitten by this one. Thanks.
Oh my days! Restuta! You saved me! Immediately I'm forking of course.
Thanks!
Great!
Thank you!
Thanks :)
Thanks!
What a hero! Just echoing the love from the folks above!
This saved me a tonne of time, thanks :D
Excellent tips. Thank you!!
Super - saved my day :-)
Thanks man! I was struggling with this for awhile! Cheers!
Amazing! Thank you.
Removing the listener works wonders, so I don't have to call .bind(this)
to avoid -as you said- creating a new function reference. I ended up doing this on my component:
export default class MyComponent extends React.Component {
componentDidMount() {
document.addEventListener('keyup', this.onKeyUp);
}
componentWillUnmount() {
document.removeEventListener('keyup', this.onKeyUp);
}
onKeyUp = (e) => {
if (e.keyCode === 27) { // ESC key
this.dismissDialog();
}
}
}
Helped me too... had to post. Thanks.
Thank you!
Brilliant. Thank you!
Thank you, helped me!
Thank you, helped me!!!!!!
Thank you!
I have two components and in both the components I am adding a hashChange listener and removing same way you told. But when first component is unmounted its hashChange event is still called and vice-versa.
What's the problem? Is it a bug?