Webcourse/12-React基础/05-React中绑定this并给函数传参的几种方式.md

245 lines
5.9 KiB
JavaScript
Raw Permalink Normal View History

## 前言
我们先来看下面这段代码
components/MyComponent.jsx
```javascript
import React from "react";
export default class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
msg: "这是 MyComponent 组件 默认的msg"
};
}
render() {
return (
<div>
<h1>绑定This并传参</h1>
<input type="button" value="绑定this并传参" onClick={this.changeMsg} />
<h3>{this.state.msg}</h3>
</div>
);
}
changeMsg() {
// 注意这里的changeMsg()只是一个普通方法。因此,在触发的时候,这里的 this 是 undefined
console.log(this); // 打印结果undefined
this.setState({
msg: "设置 msg 为新的值"
});
}
}
```
上面的代码中点击按钮执行 changeMsg() 方法尝试修改 this.state.msg 的值但是这个方法执行的时候是会报错的
```
Uncaught TypeError: Cannot read property 'setState' of null
```
而且打印this的结果也是 undefined这是为啥呢因为这里的 this 并不是指向 MyComponent 组件本身
那如何让 changeMsg() 方法里面的 this指向MyComponent 组件呢办法总是有的比如说将changeMsg() 修改为箭头函数
```javascript
changeMsg = () => {
console.log(this); // 打印结果MyComponent 组件
this.setState({
msg: "设置 msg 为新的值"
});
};
```
那么除了箭头函数可以 绑定 this还有没有其他的方式呢我们接下来讲一讲
## 绑定 this 的方式一bind()
代码举例
```javascript
import React from "react";
export default class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
msg: "这是 MyComponent 组件 默认的msg"
};
}
render() {
return (
<div>
<h1>绑定This并传参</h1>
{/* bind 的作用:为前面的函数,修改函数内部的 this 指向。让 函数内部的this指向 bind 参数列表中的 第一个参数 */}
<input
type="button"
value="绑定this并传参"
onClick={this.changeMsg1.bind(this)}
/>
<h3>{this.state.msg}</h3>
</div>
);
}
changeMsg1() {
this.setState({
msg: "设置 msg 为新的值"
});
}
}
```
上方代码中我们为什么用 bind()而不是用 call/apply 因为 bind() 并不会立即调用正是我们需要的
**注意**bind 中的第一个参数是用来修改 this 指向的第一个参数**后面的所有参数**都将作为函数的参数传递进去
我们来看看通过 bind() 是怎么传参的
**通过 bind() 绑定this并给函数传参**
```javascript
import React from "react";
export default class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
msg: "这是 MyComponent 组件 默认的msg"
};
}
render() {
return (
<div>
<h1>绑定This并传参</h1>
{/* bind 的作用:为前面的函数,修改函数内部的 this 指向。让 函数内部的this指向 bind 参数列表中的 第一个参数 */}
<input type="button" value="绑定this并传参" onClick={this.changeMsg1.bind(this, "千古啊", "壹号啊")} />
<h3>{this.state.msg}</h3>
</div>
);
}
changeMsg1(arg1, arg2) {
this.setState({
msg: "设置 msg 为新的值" + arg1 + arg2
});
}
}
```
## 绑定 this 并给函数传参 的方式二构造函数里设置 bind()
我们知道构造函数中的 this 本身就是指向组件的实例的所以我们可以在这里做一些事情
代码举例
```javascript
import React from "react";
export default class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
msg: "这是 MyComponent 组件 默认的msg"
};
// 绑定 this 并给函数传参的方式2: 在构造函数中绑定并传参
// 注意:当一个函数调用 bind 改变了this指向后bind 函数调用的结果有一个【返回值】这个值就是被改变this指向后的函数的引用。
// 也就是说: bind 不会修改 原函数的 this 指向,而是改变了 “函数拷贝”的this指向。
this.changeMsg2 = this.changeMsg2.bind(this, "千古恩", "壹号恩");
}
render() {
return (
<div>
<h1>绑定This并传参</h1>
<input type="button" value="绑定this并传参" onClick={this.changeMsg2} />
<h3>{this.state.msg}</h3>
</div>
);
}
changeMsg2(arg1, arg2) {
this.setState({
msg: "设置 msg 为新的值" + arg1 + arg2
});
}
}
```
上方代码中需要注意的是当一个函数调用 bind 改变了this指向后bind 函数调用的结果有一个返回值这个值就是被改变this指向后的函数的引用也就是说 bind 不会修改 原函数的 this 指向而是改变了 函数拷贝的this指向
2019-02-22 15:47:58 +08:00
## 绑定 this 并给函数传参 的方式三箭头函数
第三种方式用得最多
代码举例
```javascript
import React from "react";
export default class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
msg: "这是 MyComponent 组件 默认的msg"
};
}
render() {
return (
<div>
<h1>绑定This并传参</h1>
<input
type="button"
value="绑定this并传参"
onClick={() => {
this.changeMsg3("千古3", "壹号3");
}}
/>
<h3>{this.state.msg}</h3>
</div>
);
}
changeMsg3 = (arg1, arg2) => {
// console.log(this);
// 注意:这里的方式,是一个普通方法,因此,在触发的时候,这里的 this 是 undefined
this.setState({
msg: "绑定this并传参的方式3" + arg1 + arg2
});
};
}
```