react中關于函數(shù)調(diào)用()與bind this的原因及分析
關于函數(shù)調(diào)用()與bind this的原因
以下內(nèi)容主要基于onClick的回調(diào)函數(shù)解決方案
官方文檔對于jsx回調(diào)函數(shù)解釋
- 對待 JSX 回調(diào)函數(shù)中的 this,在 JavaScript 中,class 的方法默認不會綁定 this。
- 如果你忘記綁定this.handleClick 并把它傳入了 onClick,當你調(diào)用這個函數(shù)的時候 this 的值為 undefined。
//函數(shù)組件則就是 無狀態(tài)組件 ?只負責數(shù)據(jù)的展示(靜態(tài)) //類組件這就是有狀態(tài)組件 ? ? ?負責更新ui,讓頁面動起來 //狀態(tài)(state )就是數(shù)據(jù),是組件內(nèi)部的私有數(shù)據(jù),只能在組件內(nèi)部使用 //state的值是對象,即就是一個組件內(nèi)部可以擁有多個數(shù)據(jù) class StateComponent extends React.Component{ ? //使用es6簡化辦法初始化 ? //state={ ? // ?count:0 ? //} ? ?constructor(props) { ? ? super(props); ? ? this.state = {count: 0}; ? ? this.addClick3 = this.addClick3.bind(this); ? } ? addClick(){ ? ? this.setState({count : this.state.count + 1}); ? } ? addClick2=()=>{ ? ? this.setState({count : this.state.count + 1}); ? } ? addClick3(){ ? ? this.setState({count : this.state.count + 1}); ? } ? render(){ ? ? return( ? ? ? <> ? ? <button onClick={()=>{ ? ? ? this.setState({ ? ? ? ? count: this.state.count+1 ? ? ? }) ? ? }}>有狀態(tài)組件,{this.state.count}</button> ? ? <button onClick={this.addClick.bind(this)} >不使用constructor,使用注釋的es6簡化寫法</button> ? ? <button onClick={()=>this.addClick()} >箭頭函數(shù)使用</button> ? ? <button onClick={this.addClick2} >使用箭頭函數(shù)</button> ? ? <button onClick={this.addClick3} >constructor中進行綁定后可使用</button> ? ? </> ? ? ) ? } }
由于初學js以及react框架,所以對于jsx插值表達式中的函數(shù)調(diào)用有些疑問
function check(){ }
1、有些插值表達式調(diào)用函數(shù)不需要使用(),如{check};但是有些地方調(diào)用則需要使用(),如{check()}
2、在使用react中的onClick函數(shù)時,調(diào)用函數(shù)如果函數(shù)內(nèi)部沒有使用this,則可以直接調(diào)用{check};如果使用了this則需要使用特殊處理,如最頂部的代碼所示。
答1
在界面直接使用jsx插值表達式,如果是希望直接返回函數(shù)結(jié)果,需要使用{check()};如果不需要直接調(diào)用函數(shù),而是等待某些觸發(fā)條件再調(diào)用函數(shù){check}。這里函數(shù)的()即就是函數(shù)調(diào)用,而函數(shù)名是指向函數(shù)體的指針。
react官網(wǎng)對于以下問題的解答可以很好地看出()的區(qū)別
為什么我的函數(shù)每次組件渲染時都會被調(diào)用?
確保你在傳遞一個函數(shù)給組件時,沒有調(diào)用這個函數(shù):
hadleClick(){ ?return <div>hello world</div> ?//函數(shù)體內(nèi)部沒有使用this }
render() { ? // Wrong: handleClick is called instead of passed as a reference! ? return <button onClick={this.handleClick()}>Click Me</button> }
正確做法是,傳遞函數(shù)本身(不帶括號):
render() { ? // Correct: handleClick is passed as a reference! ? return <button onClick={this.handleClick}>Click Me</button> }
答2
js本身有一個特性,如果直接調(diào)用函數(shù),盡管函數(shù)內(nèi)部使用了this也可以正常使用。但是如果函數(shù)內(nèi)容使用了this,但是不是直接調(diào)用這個函數(shù),則內(nèi)部的this會丟失,this會變成undefined。
所以下面代碼中renderList()直接調(diào)用,使用{this.renderList()},盡管函數(shù)體內(nèi)部使用了this,也不需要特殊處理。
但是onClick就不是直接調(diào)用。這里的onClick就相當于一個中間量。
函數(shù)體內(nèi)部的this指向會丟失。
class Comment extends React.Component{ ? ? state={ ? ? ? ? ?comments:[ ? ? ? ? ? ? {id:1,name:'jack',comment:"沙發(fā)"}, ? ? ? ? ? ? {id:2,name:"tom",comment:'沙發(fā)不錯'}, ? ? ? ? ? ? {id:3,name:"blue",comment:"還行"} ? ? ? ? ?] ? ? } ? ? renderList(){ ? ? ? ? return( ? ? ? ? ? ? this.state.comments.kength===0? ? ? ? ? ? ? ? ? <div className="no-comment" >暫無評論,快去評論</div>: ? ? ? ? ? ? ? ? <ul > ? ? ? ? ? ? ? {this.state.comments&&this.state.comments.map(comment=> ? ? ? ? ? ? ? ? ? <li key={comment.id}><h3>評論人:{comment.name}</h3> ? ? ? ? ? ? ? ? ? <p>評論內(nèi)容 :{comment.content}</p> ? ? ? ? ? ? ? ? ? </li> ? ? ? ? ? ? ? )}? ? ? ? ? ? ? ? ?</ul> ? ? ? ? ? ? ?? ? ? ? ? ) ? ? } ? ? ? render(){ ? ? ? ? return( ? ? ? ? ? ? <> ? ? ? ? ? ? {this.renderList()} ? ? ? ? ? ? ?</> ? ? ? ? ) ? ? ? } }
this的丟失可以使用箭頭函數(shù)來解決,因為箭頭函數(shù)具有如下特質(zhì):
箭頭函數(shù)的時候,箭頭函數(shù)會默認幫我們綁定外層 this 的值,所以在箭頭函數(shù)中 this 的值和外層的 this 是一樣的。
因此可以通過使用箭頭函數(shù)避免this的丟失,當然為了避免this的丟失還有很多種方式
1、使用es5的語法,在初始化component的時候使用constructor,對函數(shù)進行綁定
2、在中間量聲明時使用bind(this) 進行綁定
3、中間量聲明函數(shù)時使用箭頭函數(shù),可以直接進行函數(shù)調(diào)用;或者將函數(shù)內(nèi)容直接書寫在箭頭函數(shù)內(nèi)(注意這里進行函數(shù)調(diào)用時需要使用函數(shù)名+(),因為在函數(shù)內(nèi)部聲明是直接調(diào)用)
4、最常用的方式,使用箭頭函數(shù)聲明函數(shù),則可以直接調(diào)用,不需要額外處理
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
React類組件中super()和super(props)的區(qū)別詳解
這篇文章給大家詳細介紹了React類組件中super()和super(props)有什么區(qū)別,文中通過代碼示例給大家介紹的非常詳細,對大家的學習或工作有一定的幫助,需要的朋友可以參考下2024-01-01基于CSS實現(xiàn)MaterialUI按鈕點擊動畫并封裝成 React 組件
筆者先后開發(fā)過基于vue,react,angular等框架的項目,碧如vue生態(tài)的elementUI, ant-design-vue, iView等成熟的UI框架, react生態(tài)的ant-design, materialUI等,這些第三方UI框架極大的降低了我們開發(fā)一個項目的成本和復雜度,使開發(fā)者更專注于實現(xiàn)業(yè)務邏輯和服務化2021-11-11詳解React-Native全球化多語言切換工具庫react-native-i18n
這篇文章主要介紹了詳解React-Native全球化語言切換工具庫react-native-i18n,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-11-11react-router 路由切換動畫的實現(xiàn)示例
這篇文章主要介紹了react-router 路由切換動畫的實現(xiàn)示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-12-12Electron整合React使用搭建開發(fā)環(huán)境的步驟詳解
這篇文章主要介紹了Electron整合React使用搭建開發(fā)環(huán)境,本文分步驟給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值 ,需要的朋友可以參考下2020-06-06React?高德地圖進京證路線規(guī)劃問題記錄(匯總)
這篇文章主要介紹了React高德地圖進京證路線規(guī)劃問題小記,本文通過實例代碼給大家介紹的非常詳細,感興趣的朋友跟隨小編一起看看吧2024-08-08