携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第11天,点击查看活动详情
前言
在 React 组件【1】中已经详细介绍了什么是 React 组件,React 组件的创建方式,React 组件的事件处理以及 React 组件中最重要的 state 和 setState()等。 但是对于 React 组件的使用,我们还需要注意以下几点:
1. 简化代码
具体做法是从 JSX 中抽离事件处理程序
- JSX 中掺杂过多 JS 逻辑代码,会显得非常混乱
- 推荐:将逻辑抽离到单独的方法中,保证 JS 结构清晰
简化后的代码如下:
class App extends React.Component{
state = {
count: 10
}
handleClick(){
this.setState({
count: this.state.count + 1
})
}
render(){
return (
<div>
<span>计数器:{this.state.count}</span>
<button onClick={this.handleClick}>+1</button>
</div>
)
}
}
ReactDOM.render(<App />,document.getElementById('root'))
运行代码,报错如下:
报错原因:事件处理程序中 this 的值为 undefined
希望:this 指向组件实例(render 方法中的 this 即为组件实例,因为 render 中用的是箭头函数,而箭头函数中没有 this,它就会去外部寻找,也就是 render,所以 this 指向的是 render 本身,如果将箭头函数改为 function 也会报错。)
由此我们可以继续引出下一点:如何解决事件绑定的 this 指向问题?
2. 事件绑定 this 指向
解决 this 指向的方法主要有以下几种:
2.1 箭头函数
- 利用箭头函数自身不绑定 this 的特点
class App extends React.Component{
state = {
count: 10
}
handleClick(){
console.log('事件处理程序中的this:',this)
this.setState({
count: this.state.count + 1
})
}
render(){
return (
<div>
<span>计数器:{this.state.count}</span>
<button onClick={() => this.handleClick()}>+1</button>
</div>
)
}
}
ReactDOM.render(<App />,document.getElementById('root'))
2.2 Function.prototype.bind()
- 利用 ES5 中的 bind 方法,将事件处理程序中的 this 与组件实例绑定到一起
class App extends React.Component{
constructor(){
super()
this.state = {
count: 10
}
this.handleClick =this.handleClick.bind(this)
}
handleClick(){
this.setState({
count: this.state.count + 1
})
}
render(){
return (
<div>
<span>计数器:{this.state.count}</span>
<button onClick={this.handleClick}>+1</button>
</div>
)
}
}
ReactDOM.render(<App />,document.getElementById('root'))
2.3 class 的实例方法(推荐)
- 利用箭头函数形式的 class 实例方法
- 注意:该语法是实验性语法,但是,由于 babel 的存在可以直接使用
class App extends React.Component{
state = {
count: 10
}
handleClick = () =>{
console.log('事件处理程序中的this:',this)
this.setState({
count: this.state.count + 1
})
}
render(){
return (
<div>
<span>计数器:{this.state.count}</span>
<button onClick={this.handleClick}>+1</button>
</div>
)
}
}
ReactDOM.render(<App />,document.getElementById('root'))