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
相关推荐
一斤代码2 小时前
vue3 下载图片(标签内容可转图)
前端·javascript·vue
中微子2 小时前
React Router 源码深度剖析解决面试中的深层次问题
前端·react.js
光影少年2 小时前
从前端转go开发的学习路线
前端·学习·golang
中微子3 小时前
React Router 面试指南:从基础到实战
前端·react.js·前端框架
3Katrina3 小时前
深入理解 useLayoutEffect:解决 UI "闪烁"问题的利器
前端·javascript·面试
前端_学习之路4 小时前
React--Fiber 架构
前端·react.js·架构
coderlin_4 小时前
BI布局拖拽 (1) 深入react-gird-layout源码
android·javascript·react.js
甜瓜看代码4 小时前
1.
react.js·node.js·angular.js
伍哥的传说4 小时前
React 实现五子棋人机对战小游戏
前端·javascript·react.js·前端框架·node.js·ecmascript·js
qq_424409194 小时前
uniapp的app项目,某个页面长时间无操作,返回首页
前端·vue.js·uni-app