react当中的this指向

绑定this常见的方法

在JavaScript当中,this的指向取决于函数调用的上下文,但是在react当中,this通常指向指向问题是一个常见的困扰,如果this没有正确绑定,那么方法中的this很可能会是undefined,导致程序出错

1.bind(this):

在构造函数当中使用.bind(this)来this的指向绑定,这个方法比较方便,绑定一次即可生效,性能比较好,但是代码比较长

Test1ConstructorBind 继承自React.Component,这是定义 React 类组件的标准方式。

在构造函数中使用this.method.bind(this)为每个事件处理方法绑定this,确保方法内部的this指向组件实例。

javascript 复制代码
import React, { Component } from 'react'

class Test1ConstructorBind extends Component {
  constructor(props) {
    super(props)
    this.state = {
      message: 'Hello!',
      count: 0,
      isVisible: true,
    }
    this.handleClick = this.handleClick.bind(this)
    this.handleCount = this.handleCount.bind(this)
    this.toggleVisibility = this.toggleVisibility.bind(this)
    this.handleReset = this.handleReset.bind(this)
  }
  //切换消息文本
  handleClick() {
    console.log('方法1 - 构造函数绑定: 当前消息:', this.state.message)
    this.setState({
      message: this.state.message === 'Hello!' ? '你好!' : 'Hello!',
    })
  }
  //增加计数
  handleCount() {
    this.setState((prevState) => ({
      count: prevState.count + 1,
    }))
  }
  //切换内容显示 / 隐藏
  toggleVisibility() {
    this.setState((prevState) => ({
      isVisible: !prevState.isVisible,
    }))
  }
  //重置所有状态
  handleReset() {
    this.setState({
      count: 0,
      message: 'Hello!',
      isVisible: true,
    })
  }

  render() {
    return (
      <div>
        <h2>方法1: 构造函数中绑定 this</h2>
        <p>在 constructor 中使用 this.method = this.method.bind(this) 绑定</p>
        <button onClick={this.handleClick}>切换消息</button>
        <span> 当前消息: {this.state.message}</span>
        <br />
        <button onClick={this.handleCount}>增加计数</button>
        <span> 计数: {this.state.count}</span>
        <br />
        <button onClick={this.toggleVisibility}>
          {this.state.isVisible ? '隐藏' : '显示'}内容
        </button>
        {this.state.isVisible && <div>这是可以切换显示/隐藏的内容</div>}
        <br />
        <button onClick={this.handleReset}>重置所有状态</button>
      </div>
    )
  }
}

export default Test1ConstructorBind

2.使用箭头函数:

箭头函数不绑定自己的this,它会捕获所在上下文的this值,使用这种方法无需手动绑定,每次渲染的时候需要创建两个函数实例,可能会影响性能

javascript 复制代码
import React, { Component } from 'react'

class Test2ArrowFunction extends Component {
  constructor(props) {
    super(props)
    this.state = {
      message: 'Hello!',
      count: 0,
      isVisible: true,
    }
    // 使用箭头函数时,不需要在构造函数中绑定
  }

  // 方法2: 使用箭头函数自动绑定this
  handleClick = () => {
    console.log('方法2 - 箭头函数: 当前消息:', this.state.message)
    this.setState({
      message: this.state.message === 'Hello!' ? '你好!' : 'Hello!',
    })
  }

  handleCount = () => {
    this.setState((prevState) => ({
      count: prevState.count + 1,
    }))
  }

  toggleVisibility = () => {
    this.setState((prevState) => ({
      isVisible: !prevState.isVisible,
    }))
  }

  handleReset = () => {
    this.setState({
      count: 0,
      message: 'Hello!',
      isVisible: true,
    })
  }

  render() {
    return (
      <div>
        <h2>方法2: 箭头函数自动绑定 this</h2>
        <p>使用箭头函数语法,this 自动绑定到组件实例</p>
        <button onClick={this.handleClick}>切换消息</button>
        <span> 当前消息: {this.state.message}</span>
        <br />
        <button onClick={this.handleCount}>增加计数</button>
        <span> 计数: {this.state.count}</span>
        <br />
        <button onClick={this.toggleVisibility}>
          {this.state.isVisible ? '隐藏' : '显示'}内容
        </button>
        {this.state.isVisible && <div>这是可以切换显示/隐藏的内容</div>}
        <br />
        <button onClick={this.handleReset}>重置所有状态</button>
      </div>
    )
  }
}

export default Test2ArrowFunction

3.使用内联bind:

组件较小且方法简单,需要快速传递参数,方法只在一处使用,无需复用。

大型列表渲染,性能敏感的组件,方法需要被多次复用(如传递给子组件)。

javascript 复制代码
import React, { Component } from 'react'

class Test4InlineBind extends Component {
  constructor(props) {
    super(props)
    this.state = {
      message: 'Hello!',
      count: 0,
      isVisible: true,
    }
  }

  handleClick() {
    console.log('方法4 - 内联bind: 当前消息:', this.state.message)
    this.setState({
      message: this.state.message === 'Hello!' ? '你好!' : 'Hello!',
    })
  }

  handleCount() {
    this.setState((prevState) => ({
      count: prevState.count + 1,
    }))
  }

  toggleVisibility() {
    this.setState((prevState) => ({
      isVisible: !prevState.isVisible,
    }))
  }

  handleReset() {
    this.setState({
      count: 0,
      message: 'Hello!',
      isVisible: true,
    })
  }

  render() {
    return (
      <div>
        <h2>方法4: 内联 bind 方法</h2>
        <p>
          在 render 中使用 onClick=this.handleClick.bind(this) 语法(性能较差)
        </p>
        <button onClick={this.handleClick.bind(this)}>切换消息</button>
        <span> 当前消息: {this.state.message}</span>
        <br />
        <button onClick={this.handleCount.bind(this)}>增加计数</button>
        <span> 计数: {this.state.count}</span>
        <br />
        <button onClick={this.toggleVisibility.bind(this)}>
          {this.state.isVisible ? '隐藏' : '显示'}内容
        </button>
        {this.state.isVisible && <div>这是可以切换显示/隐藏的内容</div>}
        <br />
        <button onClick={this.handleReset.bind(this)}>重置所有状态</button>
        <div>
          <small>
            注意:这种方法每次渲染都会创建新的函数,影响性能,不推荐在生产环境中使用。
          </small>
        </div>
      </div>
    )
  }
}

export default Test4InlineBind

4.使用内联箭头函数:

语法简洁,自动绑定this,可直接传递参数

每次渲染都会创建新的函数实例,可能影响性能

javascript 复制代码
import React, { Component } from 'react'

class Test3InlineArrow extends Component {
  constructor(props) {
    super(props)
    this.state = {
      message: 'Hello!',
      count: 0,
      isVisible: true,
    }
  }

  render() {
    return (
      <div>
        <h2>方法3: 内联箭头函数</h2>
        <p>
          在 render 中使用 onClick={() => this.handleClick()} 语法(性能较差)
        </p>
        <button
          onClick={() => {
            console.log('方法3 - 内联箭头函数: 当前消息:', this.state.message)
            this.setState({
              message: this.state.message === 'Hello!' ? '你好!' : 'Hello!',
            })
          }}
        >
          切换消息
        </button>
        <span> 当前消息: {this.state.message}</span>
        <br />
        <button
          onClick={() => {
            this.setState((prevState) => ({
              count: prevState.count + 1,
            }))
          }}
        >
          增加计数
        </button>
        <span> 计数: {this.state.count}</span>
        <br />
        <button
          onClick={() => {
            this.setState((prevState) => ({
              isVisible: !prevState.isVisible,
            }))
          }}
        >
          {this.state.isVisible ? '隐藏' : '显示'}内容
        </button>
        {this.state.isVisible && <div>这是可以切换显示/隐藏的内容</div>}
        <br />
        <button
          onClick={() => {
            this.setState({
              count: 0,
              message: 'Hello!',
              isVisible: true,
            })
          }}
        >
          重置所有状态
        </button>
        <div>
          <small>
            注意:这种方法每次渲染都会创建新的函数,影响性能,不推荐在生产环境中使用。
          </small>
        </div>
      </div>
    )
  }
}

export default Test3InlineArrow
相关推荐
_一两风1 分钟前
JS执行机制-event loop
javascript
止观止2 分钟前
JavaScript对象创建9大核心技术解析
开发语言·javascript·ecmascript
摆烂为不摆烂3 分钟前
😁深入JS(五): 一文让你完全理解 hash 与 history 路由,手写前端路由
前端
1024小神3 分钟前
cocos游戏开发中,如何制作一个空气墙
前端·javascript
爱编程的喵3 分钟前
深入理解JavaScript事件循环机制:从同步到异步的完整解析
前端·javascript
20264 分钟前
11. vite打包优化
前端·javascript·vite
拾光拾趣录9 分钟前
组件封装的⼀些基本准则
前端·前端工程化
CAD老兵10 分钟前
TypeScript 中如何转换两个具有相同值的枚举类型?
前端
1024小神14 分钟前
Cocos游戏开发中,检测两个物体碰撞,并实现物理反弹逻辑
前端·javascript