react中這些細(xì)節(jié)你注意過沒有?下面本篇文章給大家總結(jié)了一些你可能沒注意的react細(xì)節(jié)知識(shí)點(diǎn)。有一定的參考價(jià)值,有需要的朋友可以參考一下,希望對(duì)大家有所幫助。
【相關(guān)教程推薦:React視頻教程】
react中的一些細(xì)節(jié)知識(shí)點(diǎn):
1、組件中g(shù)et的使用(作為類的getter)
ES6知識(shí):class類也有自己的getter和setter,寫法如下:
Class Component { constructor() { super() this.name = '' } // name的getter get name() { ... } // name的setter set name(value) { ... } }
react組件中的get的使用如下:
/* * renderFullName的getter * 可以直接在render中使用this.renderFullName */ get renderFullName () { return `${this.props.firstName} ${this.props.lastName}`; } render() { return ( <div>{this.renderFullName}</div> ) }
那getter在react組件中有什么用處呢??
constructor (props) { super() this.state = {}; } render () { // 常規(guī)寫法,在render中直接計(jì)算 var fullName = `${this.props.firstName} ${this.props.lastName}`; return ( <div> <h2>{fullName}</h2> </div> ); }
// 較為優(yōu)雅的寫法:,減少render函數(shù)的臃腫 renderFullName () { return `${this.props.firstName} ${this.props.lastName}`; } render () { var fullName = this.renderFullName() <div>{ fullName }</div> }
// 推薦的做法:通過getter而不是函數(shù)形式,減少變量 get renderFullName () { return `${this.props.firstName} ${this.props.lastName}`; } render () { <div>{ this.renderFullName }</div> }
如果你了解Vue的話,那么你知道其中的 computed: {} 計(jì)算屬性,它的底層也是使用了getter,只不過是對(duì)象的getter不是類的getter
// 計(jì)算屬性,計(jì)算renderFullName computed: { renderFullName: () => { return `${this.firstName} ${this.lastName}`; } }
Vue的computed有一個(gè)優(yōu)勢(shì)就是:
計(jì)算屬性對(duì)比函數(shù)執(zhí)行:會(huì)有緩存,減少計(jì)算 —> 計(jì)算屬性只有在它的相關(guān)依賴發(fā)生改變時(shí)才會(huì)重新求值。
這就意味著只要 firstName和lastName還沒有發(fā)生改變,多次訪問renderFullName計(jì)算屬性會(huì)立即返回之前的計(jì)算結(jié)果,而不必再次執(zhí)行函數(shù)。
那么是否react的getter也有緩存這個(gè)優(yōu)勢(shì)嗎??? 答案是:沒有,react中的getter并沒有做緩存優(yōu)化!
2、組件的attr及事件執(zhí)行順序:
A、父子組件:以props形式,父?jìng)鬟f給子
B、同一組件:后面覆蓋前面。
依靠上述規(guī)則,那么要使得 attr 的權(quán)重最高,應(yīng)該放到最底層的組件中,而且位置盡量的靠后。
<-- 父組件Parent | 調(diào)用子組件并傳遞onChange屬性 --> <div> <Child onChange={this.handleParentChange} /> </div> <-- 子組件Child | 接收父組件onChange, 自己也有onChange屬性 --> <input {...this.props} onChange={this.handleChildChange} />
此時(shí),Child組件執(zhí)行的onChange只是執(zhí)行handleChildChange事件,handleParentChange事件并不會(huì)執(zhí)行.
- 1.如果只需要執(zhí)行handleParentChange怎么辦?? input中 {…this.props} 與 onChange={this.handleChildChange} 換個(gè)位置。
- 2.如果兩個(gè)事件都需要執(zhí)行怎么辦?? 在Child組件中 handleChildChange 中執(zhí)行 this.props.handleParentChange
3、類中的方法用ES6形式簡(jiǎn)寫的不同之處: fn = () => {} 與 fn() {} 的區(qū)別:
export default Class Child extends Component { constructor (props) { super() this.state = {}; } // 寫法1,這是ES6的類的方法寫法 fn1() { console.log(this) // 輸出 undefined } // 寫法2,這是react的方法寫法 fn2 = () => { console.log(this) // 輸出:Child {props: {…}, context: {…}, refs: {…}, …} } render () { return ( <div> <button onClick={this.fn1}>fn1方法執(zhí)行</button > <button onClick={this.fn2}>fn2方法執(zhí)行</button > </div> ); } }
可見兩種寫法,函數(shù)內(nèi)的this指向時(shí)不同的。
那它們就沒有相同之處嗎??, 以下三種情況是相同的:
情況1:函數(shù)內(nèi)部用不到this的時(shí)候,兩者相等。
// 寫法1,這是ES6的類的方法寫法 fn1() { return 1 + 1 } // 寫法2,這是react的方法寫法 fn2 = () => { return 1 + 1 }
情況2:兩者在render中直接執(zhí)行的時(shí)候。
// 寫法1,這是ES6的類的方法寫法 fn1() { console.log(this) // Child {props: {…}, context: {…}, refs: {…}, …} } // 寫法2,這是react的方法寫法 fn2 = () => { console.log(this) // 輸出:Child {props: {…}, context: {…}, refs: {…}, …} } render () { return ( <div> <button onClick={() => { this.fn1(); }}>fn1方法執(zhí)行</button > <button onClick={() => { this.fn2(); }}>fn2方法執(zhí)行</button > </div> ); }
情況3:給this.fn2.bind(this),綁定this作用上下文。
// 寫法1,這是ES6的類的方法寫法 fn1() { console.log(this) // Child {props: {…}, context: {…}, refs: {…}, …} } // 寫法2,這是react的方法寫法 fn2 = () => { console.log(this) // 輸出:Child {props: {…}, context: {…}, refs: {…}, …} } render () { return ( <div> <button onClick={this.fn1}>fn1方法執(zhí)行</button > <button onClick={this.fn2.bind(this)}>fn2方法執(zhí)行</button > </div> ); }
注意,不要和ES6中對(duì)象的方法簡(jiǎn)寫弄混了,以下是對(duì)象Obeject的方法簡(jiǎn)寫:
阮一峰ES6: http://es6.ruanyifeng.com/#docs/object
4、列表渲染中的數(shù)組
參考:https://doc.react-china.org/docs/lists-and-keys.html
正常的jsx寫法是在render中寫類似于HTML的語法,標(biāo)簽嵌套標(biāo)簽<p><input /></p>,有js,用 { 花括號(hào) }。
但是不知道你注意過沒有,數(shù)組可以嵌套在標(biāo)簽內(nèi)部,正常渲染。
function NumberList(props) { const numbers = [1,2,3,4,5]; // listItems是數(shù)組numbers通過map返回的,本質(zhì)也是個(gè)數(shù)組。 const listItems = numbers.map((number) => <li>{number}</li> ); return ( <ul> // 可以替換成 [ <li>1</li>, <li>2</li>, .....] {listItems} </ul> ); }
如上所示,標(biāo)簽內(nèi)部的數(shù)組是可以正確渲染的,那么就有以下的寫法:
renderItem(name) { const A = <li key={'a'}>A</li>, B = <li key={'b'}>B</li>, C = <li key={'c'}>C</li>, D = <li key={'d'}>D</li>; let operationList; switch (name) { case 1: operationList = [A , B, C] break; case 2: operationList = [B, C, D] break; case 0: operationList = [A] break; } return operationList; } render() { // this.renderItem() 執(zhí)行結(jié)果是數(shù)組 return ( <ul>{ this.renderItem() }</ul> ) }