An ancient pit
<Form
submit={this.submit.bind(this)}
>
</Form>
Copy the code
This is the kind of code many of you have seen when I want to bind a method inside a component to the DOM to execute a call, in order to bind the scope of this.
But recently, I heard a colleague’s share that THERE are problems with BIND.
MDN Document
“The bind() function creates a new function (a bound function) with the same function body as the function it is being called on with the this value bound to the first argument of bind(), which cannot be overridden.”
Bind creates a new function whose first argument is the bind’s this, which is not overridden.
However, the bug encountered by my colleagues happened to be the case where this in the function did not match our expectations after using bind to bind this.
The bug went on for a long time with sporadic feedback, but the cause was never found, including when compatibility tests in various Windows browsers failed to reproduce.
Some time ago, I finally found a user who could stably reproduce this bug, and operated their computer remotely. Finally, I found that there was a value in the above this.submit function, which was normal in all other places, but was lost in the Form submit and changed to undefined. The result is that bind’s this scope may not be as expected in some versions of the browser, and will be written as an arrow function instead.
Although I encountered this problem, I have checked a lot of information myself and could not find out which specific versions of browsers have this problem. Therefore, I can only use the bind method to bind this as little as possible in future code writing.
Bind to this
<Button onClick={this.handleClick.bind(this)}>click me</Button>
<Button onClick={() => this.handleClick()}>click me</Button>
Copy the code
React components bind this to components. However, these two methods do not conform to the react specification. There are two reasons:
this
The direction of is not very clear.bind
Both the arrow function and the parent component return a new function each timererender
Will result in sub-componentsrerender
.
React’s official recommendation is to bind this to constructor or declare methods directly from components using arrow functions.
class App extends Component {
constructor() {
this.handleClick = this.handleClick.bind(this);
}
handleSubmit = (a)= > {
}
render() {
return(...). ; }}Copy the code
This way we can avoid unnecessary rerendering of child components.
Methods with arguments
This brings us to the next problem, what if we run into methods that take parameters?
For example, to click a button, we need to remove an element based on its ID.
The first option is to bind the required value of the parameter to the corresponding DOM element value, so that we can use e.target. Value.
export default class Toggle extends Component {
deleteButton = (e) = > {
const id = e.target.value;
}
render() {
const { user } = this.props;
return (
<button onClick={this.deleteButton} value={user.id}>Toggle Button</button>); }}Copy the code
The second method is to create a layer of functions that handle the e argument of the click event, and the other arguments are handled and passed inside the function.
export default class Toggle extends Component {
deleteButton = (id) = > {
// ...
}
handleDeleteButton = e= > {
const id = this.props.user.id;
this.deleteButton(id);
}
render() {
return (
<button onClick={this.deleteButton} value={user.id}>Toggle Button</button>); }}Copy the code
teasing
I know how this works, and I know how to minimize the performance penalty by using the bind and arrow functions when binding dom methods, but it’s really cool. [head]
Permanent AD
Toutiao international team has been hiring for a long time
Intern and society recruit want, what post be short of ~
Please send your resume to [email protected]
[funny]