react中this指向的使用小結(jié)
在JavaScript當(dāng)中,this的指向取決于函數(shù)調(diào)用的上下文,但是在react當(dāng)中,this通常指向指向問題是一個(gè)常見的困擾,如果this沒有正確綁定,那么方法中的this很可能會是undefined,導(dǎo)致程序出錯(cuò)
講之前,先回顧一下JavaScript當(dāng)中的this指向
this表示函數(shù)(方法)當(dāng)前所關(guān)聯(lián)的對象,并且this的指向是動態(tài)的,this的指向完全取決于函數(shù)的調(diào)用方式
JavaScript當(dāng)中this指向:
定義:
this表示函數(shù)(方法)當(dāng)前所關(guān)聯(lián)的對象,并且this的指向是動態(tài)的,this的指向完全取決于函數(shù)的調(diào)用方式,誰調(diào)用函數(shù),this 就指向誰(箭頭函數(shù)和 bind 是例外,需單獨(dú)記憶)
this常見的指向:
1.在普通函數(shù)當(dāng)中:
function a() {
console.log(this) //window
}
a()在這種非嚴(yán)格情況下,函數(shù)當(dāng)中的this指向全局window
"use strict"
function a() {
console.log(this) //undefined
}
a()
在這種情況下,嚴(yán)格模式下的全局就是undefined,所以this指向undefined
2.在對象當(dāng)中
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 指向全局對象(非嚴(yán)格模式下是window)
}
};
var a = person.sayHi;
a() //window在這種情況中,輸出的是window,然后在嚴(yán)格模式下指向的是undefined
3.特殊情況
箭頭函數(shù):
箭頭函數(shù)沒有自己的this,它繼承的是外層作用域的this
const obj = {
name: "bob",
fuc: function () {
const arrowFunc = () => {
console.log(this)
}
arrowFunc()
}
}
obj.fuc() //obj事件處理函數(shù)的 this 指向觸發(fā)事件的 DOM 元素。
const btn = document.querySelector(".btn")
btn.addEventListener("click", function () {
console.log(this) //btn
})手動指向:
只有函數(shù)對象能夠使用apply、call和bind方法 主要作用就是改變函數(shù)執(zhí)行時(shí)this的指向,并且立即執(zhí)行該函數(shù)
call:
const person = {
fullName: function (city, country) {
console.log(this.firstName + " " + this.lastName + " 正準(zhǔn)備去 " + city + ", " + country + ".");
}
}
const person1 = {
firstName: "John",
lastName: "Doe"
}
person.fullName("Oslo", "Norway");
// 輸出: John Doe 正準(zhǔn)備去 Oslo, Norway.apply:
const person = {
fullName: function (city, country) {
console.log(this.firstName + " " + this.lastName + " 正準(zhǔn)備去 " + city + ", " + country + ".");
}
}
const person1 = {
firstName: "John",
lastName: "Doe"
}
person.fullName.apply(person1, ["Oslo", "Norway"]);
// 輸出: John Doe 正準(zhǔn)備去 Oslo, Norway.bind:
const person = {
fullName: function (city, country) {
console.log(this.firstName + " " + this.lastName + " 正準(zhǔn)備去 " + city + ", " + country + ".");
}
}
const person1 = {
firstName: "John",
lastName: "Doe"
}
const func = person.fullName.bind(person1);
func("Oslo", "Norway");
// 輸出: John Doe 正準(zhǔn)備去 Oslo, Norway.
person.fullName.bind(person1, "Oslo", "Norway")()
react當(dāng)中的綁定this指向:
1.bind(this):
在構(gòu)造函數(shù)當(dāng)中使用.bind(this)來this的指向綁定,這個(gè)方法比較方便,綁定一次即可生效,性能比較好,但是代碼比較長
Test1ConstructorBind 繼承自React.Component,這是定義 React 類組件的標(biāo)準(zhǔn)方式。
在構(gòu)造函數(shù)中使用this.method.bind(this)為每個(gè)事件處理方法綁定this,確保方法內(nèi)部的this指向組件實(shí)例。
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 - 構(gòu)造函數(shù)綁定: 當(dāng)前消息:', this.state.message)
this.setState({
message: this.state.message === 'Hello!' ? '你好!' : 'Hello!',
})
}
//增加計(jì)數(shù)
handleCount() {
this.setState((prevState) => ({
count: prevState.count + 1,
}))
}
//切換內(nèi)容顯示 / 隱藏
toggleVisibility() {
this.setState((prevState) => ({
isVisible: !prevState.isVisible,
}))
}
//重置所有狀態(tài)
handleReset() {
this.setState({
count: 0,
message: 'Hello!',
isVisible: true,
})
}
render() {
return (
<div>
<h2>方法1: 構(gòu)造函數(shù)中綁定 this</h2>
<p>在 constructor 中使用 this.method = this.method.bind(this) 綁定</p>
<button onClick={this.handleClick}>切換消息</button>
<span> 當(dāng)前消息: {this.state.message}</span>
<br />
<button onClick={this.handleCount}>增加計(jì)數(shù)</button>
<span> 計(jì)數(shù): {this.state.count}</span>
<br />
<button onClick={this.toggleVisibility}>
{this.state.isVisible ? '隱藏' : '顯示'}內(nèi)容
</button>
{this.state.isVisible && <div>這是可以切換顯示/隱藏的內(nèi)容</div>}
<br />
<button onClick={this.handleReset}>重置所有狀態(tài)</button>
</div>
)
}
}
export default Test1ConstructorBind
2.使用箭頭函數(shù):
箭頭函數(shù)不綁定自己的this,它會捕獲所在上下文的this值,使用這種方法無需手動綁定,每次渲染的時(shí)候需要創(chuàng)建兩個(gè)函數(shù)實(shí)例,可能會影響性能
import React, { Component } from 'react'
class Test2ArrowFunction extends Component {
constructor(props) {
super(props)
this.state = {
message: 'Hello!',
count: 0,
isVisible: true,
}
// 使用箭頭函數(shù)時(shí),不需要在構(gòu)造函數(shù)中綁定
}
// 方法2: 使用箭頭函數(shù)自動綁定this
handleClick = () => {
console.log('方法2 - 箭頭函數(shù): 當(dāng)前消息:', 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: 箭頭函數(shù)自動綁定 this</h2>
<p>使用箭頭函數(shù)語法,this 自動綁定到組件實(shí)例</p>
<button onClick={this.handleClick}>切換消息</button>
<span> 當(dāng)前消息: {this.state.message}</span>
<br />
<button onClick={this.handleCount}>增加計(jì)數(shù)</button>
<span> 計(jì)數(shù): {this.state.count}</span>
<br />
<button onClick={this.toggleVisibility}>
{this.state.isVisible ? '隱藏' : '顯示'}內(nèi)容
</button>
{this.state.isVisible && <div>這是可以切換顯示/隱藏的內(nèi)容</div>}
<br />
<button onClick={this.handleReset}>重置所有狀態(tài)</button>
</div>
)
}
}
export default Test2ArrowFunction
3.使用內(nèi)聯(lián)bind:
組件較小且方法簡單,需要快速傳遞參數(shù),方法只在一處使用,無需復(fù)用。
大型列表渲染,性能敏感的組件,方法需要被多次復(fù)用(如傳遞給子組件)。
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 - 內(nèi)聯(lián)bind: 當(dāng)前消息:', 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: 內(nèi)聯(lián) bind 方法</h2>
<p>
在 render 中使用 onClick=this.handleClick.bind(this) 語法(性能較差)
</p>
<button onClick={this.handleClick.bind(this)}>切換消息</button>
<span> 當(dāng)前消息: {this.state.message}</span>
<br />
<button onClick={this.handleCount.bind(this)}>增加計(jì)數(shù)</button>
<span> 計(jì)數(shù): {this.state.count}</span>
<br />
<button onClick={this.toggleVisibility.bind(this)}>
{this.state.isVisible ? '隱藏' : '顯示'}內(nèi)容
</button>
{this.state.isVisible && <div>這是可以切換顯示/隱藏的內(nèi)容</div>}
<br />
<button onClick={this.handleReset.bind(this)}>重置所有狀態(tài)</button>
<div>
<small>
注意:這種方法每次渲染都會創(chuàng)建新的函數(shù),影響性能,不推薦在生產(chǎn)環(huán)境中使用。
</small>
</div>
</div>
)
}
}
export default Test4InlineBind
4.使用內(nèi)聯(lián)箭頭函數(shù):
語法簡潔,自動綁定this,可直接傳遞參數(shù)
每次渲染都會創(chuàng)建新的函數(shù)實(shí)例,可能影響性能
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: 內(nèi)聯(lián)箭頭函數(shù)</h2>
<p>
在 render 中使用 onClick={() => this.handleClick()} 語法(性能較差)
</p>
<button
onClick={() => {
console.log('方法3 - 內(nèi)聯(lián)箭頭函數(shù): 當(dāng)前消息:', this.state.message)
this.setState({
message: this.state.message === 'Hello!' ? '你好!' : 'Hello!',
})
}}
>
切換消息
</button>
<span> 當(dāng)前消息: {this.state.message}</span>
<br />
<button
onClick={() => {
this.setState((prevState) => ({
count: prevState.count + 1,
}))
}}
>
增加計(jì)數(shù)
</button>
<span> 計(jì)數(shù): {this.state.count}</span>
<br />
<button
onClick={() => {
this.setState((prevState) => ({
isVisible: !prevState.isVisible,
}))
}}
>
{this.state.isVisible ? '隱藏' : '顯示'}內(nèi)容
</button>
{this.state.isVisible && <div>這是可以切換顯示/隱藏的內(nèi)容</div>}
<br />
<button
onClick={() => {
this.setState({
count: 0,
message: 'Hello!',
isVisible: true,
})
}}
>
重置所有狀態(tài)
</button>
<div>
<small>
注意:這種方法每次渲染都會創(chuàng)建新的函數(shù),影響性能,不推薦在生產(chǎn)環(huán)境中使用。
</small>
</div>
</div>
)
}
}
export default Test3InlineArrow
到此這篇關(guān)于react中this指向的使用小結(jié)的文章就介紹到這了,更多相關(guān)react this指向內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
react-router 路由切換動畫的實(shí)現(xiàn)示例
這篇文章主要介紹了react-router 路由切換動畫的實(shí)現(xiàn)示例,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-12-12
React-Native之截圖組件react-native-view-shot的介紹與使用小結(jié)
這篇文章主要介紹了React-Native之截圖組件react-native-view-shot的介紹與使用小結(jié),需本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,要的朋友可以參考下2021-08-08
react創(chuàng)建項(xiàng)目啟動報(bào)錯(cuò)的完美解決方法
這篇文章主要介紹了react創(chuàng)建項(xiàng)目啟動報(bào)錯(cuò)的完美解決方法,全稱為Node Package Manager,是隨同NodeJS一起安裝的包管理工具,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2022-08-08
React Navigation 使用中遇到的問題小結(jié)
本篇文章主要介紹了React Navigation 使用中遇到的問題小結(jié),主要是安卓和iOS中相對不協(xié)調(diào)的地方,特此記錄,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-05-05

