React

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > javascript类库 > React > react this指向

react中this指向的使用小结

作者:超级无敌大蟑王

JavaScript中this指向取决于调用方式,React中需绑定this以防undefined,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来一起学习学习吧

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

讲之前,先回顾一下JavaScript当中的this指向

this表示函数(方法)当前所关联的对象,并且this的指向是动态的,this的指向完全取决于函数的调用方式

JavaScript当中this指向:

定义:

 this表示函数(方法)当前所关联的对象,并且this的指向是动态的,this的指向完全取决于函数的调用方式,谁调用函数,this 就指向谁(箭头函数和 bind 是例外,需单独记忆)

this常见的指向:

1.在普通函数当中:

    function a() {
      console.log(this) //window
    }
    a()

在这种非严格情况下,函数当中的this指向全局window

    "use strict"
    function a() {
      console.log(this) //undefined
    }
    a()

在这种情况下,严格模式下的全局就是undefined,所以this指向undefined

2.在对象当中

    const person = {
      name: 'cheery',
      "sayHi": function () {
        console.log(this.name); // this 指向person
      }
    };
    person.sayHi()

在这种情况中,this指向person,然后输出的是"Alice"

    const person = {
      "sayHi": function () {
        console.log(this); // this 指向全局对象(非严格模式下是window)
      }
    };
    var a = person.sayHi;
    a() //window

在这种情况中,输出的是window,然后在严格模式下指向的是undefined 

3.特殊情况

箭头函数:
箭头函数没有自己的this,它继承的是外层作用域的this

const obj = {
      name: "bob",
      fuc: function () {
        const arrowFunc = () => {
          console.log(this)
        }
        arrowFunc()
      }
    }
    obj.fuc() //obj

事件处理函数的 this 指向触发事件的 DOM 元素。

    const btn = document.querySelector(".btn")
    btn.addEventListener("click", function () {
      console.log(this) //btn
    })

手动指向:

只有函数对象能够使用apply、call和bind方法   主要作用就是改变函数执行时this的指向,并且立即执行该函数

call:

  const person = {
    fullName: function (city, country) {
    console.log(this.firstName + " " + this.lastName + " 正准备去 " + city + ", " + country + ".");
    }
    }
    const person1 = {
    firstName: "John",
    lastName: "Doe"
    }
    person.fullName("Oslo", "Norway");
    // 输出: John Doe 正准备去 Oslo, Norway.

apply:

const person = {
    fullName: function (city, country) {
    console.log(this.firstName + " " + this.lastName + " 正准备去 " + city + ", " + country + ".");
    }
    }
    const person1 = {
    firstName: "John",
    lastName: "Doe"
    }
    person.fullName.apply(person1, ["Oslo", "Norway"]);
    // 输出: John Doe 正准备去 Oslo, Norway.

bind:

    const person = {
    fullName: function (city, country) {
    console.log(this.firstName + " " + this.lastName + " 正准备去 " + city + ", " + country + ".");
    }
   }
    const person1 = {
    firstName: "John",
    lastName: "Doe"
    }
    const func = person.fullName.bind(person1);
    func("Oslo", "Norway");
    // 输出: John Doe 正准备去 Oslo, Norway.
    person.fullName.bind(person1, "Oslo", "Norway")()

react当中的绑定this指向:

1.bind(this):

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

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

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

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值,使用这种方法无需手动绑定,每次渲染的时候需要创建两个函数实例,可能会影响性能

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:

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

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

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,可直接传递参数

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

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

到此这篇关于react中this指向的使用小结的文章就介绍到这了,更多相关react this指向内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文