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
相关推荐
慧一居士22 分钟前
flex 布局完整功能介绍和示例演示
前端
DoraBigHead24 分钟前
小哆啦解题记——两数失踪事件
前端·算法·面试
一斤代码6 小时前
vue3 下载图片(标签内容可转图)
前端·javascript·vue
中微子6 小时前
React Router 源码深度剖析解决面试中的深层次问题
前端·react.js
光影少年6 小时前
从前端转go开发的学习路线
前端·学习·golang
中微子6 小时前
React Router 面试指南:从基础到实战
前端·react.js·前端框架
3Katrina6 小时前
深入理解 useLayoutEffect:解决 UI "闪烁"问题的利器
前端·javascript·面试
前端_学习之路7 小时前
React--Fiber 架构
前端·react.js·架构
coderlin_7 小时前
BI布局拖拽 (1) 深入react-gird-layout源码
android·javascript·react.js
甜瓜看代码8 小时前
1.
react.js·node.js·angular.js