ES6知識:class類也有本身的getter和setter,寫法以下:html
Class Component { constructor() { super() this.name = '' } // name的getter get name() { ... } // name的setter set name(value) { ... } }
react組件中的get的使用以下:react
/* * renderFullName的getter * 能夠直接在render中使用this.renderFullName */ get renderFullName () { return `${this.props.firstName} ${this.props.lastName}`; } render() { return ( <div>{this.renderFullName}</div> ) }
那getter在react組件中有什麼用處呢??es6
constructor (props) { super() this.state = {}; } render () { // 常規寫法,在render中直接計算 var fullName = `${this.props.firstName} ${this.props.lastName}`; return ( <div> <h2>{fullName}</h2> </div> ); }
// 較爲優雅的寫法:,減小render函數的臃腫 renderFullName () { return `${this.props.firstName} ${this.props.lastName}`; } render () { var fullName = this.renderFullName()
<div>{ fullName }</div>
}
// 推薦的作法:經過getter而不是函數形式,減小變量 get renderFullName () { return `${this.props.firstName} ${this.props.lastName}`; } render () { <div>{ this.renderFullName }</div> }
若是你瞭解Vue的話,那麼你知道其中的 computed: {} 計算屬性,它的底層也是使用了getter,只不過是對象的getter不是類的getter數組
// 計算屬性,計算renderFullName computed: { renderFullName: () => { return `${this.firstName} ${this.lastName}`; } }
Vue的computed有一個優點就是:緩存
計算屬性對比函數執行:會有緩存,減小計算 ---> 計算屬性只有在它的相關依賴發生改變時纔會從新求值。函數
這就意味着只要 firstName和lastName尚未發生改變,屢次訪問renderFullName計算屬性會當即返回以前的計算結果,而沒必要再次執行函數。優化
那麼是否react的getter也有緩存這個優點嗎??? 答案是:沒有,react中的getter並無作緩存優化!this
A、父子組件:以props形式,父傳遞給子spa
B、同一組件:後面覆蓋前面。code
依靠上述規則,那麼要使得 attr 的權重最高,應該放到最底層的組件中,並且位置儘可能的靠後。
<-- 父組件Parent | 調用子組件並傳遞onChange屬性 --> <div> <Child onChange={this.handleParentChange} /> </div> <-- 子組件Child | 接收父組件onChange, 本身也有onChange屬性 --> <input {...this.props} onChange={this.handleChildChange} />
此時,Child組件執行的onChange只是執行handleChildChange事件,handleParentChange事件並不會執行.
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方法執行</button > <button onClick={this.fn2}>fn2方法執行</button > </div> ); } }
可見兩種寫法,函數內的this指向時不一樣的。
那它們就沒有相同之處嗎??, 如下三種狀況是相同的:
狀況1:函數內部用不到this的時候,二者相等。
// 寫法1,這是ES6的類的方法寫法 fn1() { return 1 + 1 } // 寫法2,這是react的方法寫法 fn2 = () => { return 1 + 1 }
狀況2:二者在render中直接執行的時候。
// 寫法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方法執行</button > <button onClick={() => { this.fn2(); }}>fn2方法執行</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方法執行</button > <button onClick={this.fn2.bind(this)}>fn2方法執行</button > </div> ); }
注意,不要和ES6中對象的方法簡寫弄混了,如下是對象Obeject的方法簡寫:
阮一峯ES6: http://es6.ruanyifeng.com/#docs/object
參考:https://doc.react-china.org/docs/lists-and-keys.html
正常的jsx寫法是在render中寫相似於HTML的語法,標籤嵌套標籤<div><input /></div>,有js,用 { 花括號 }。
可是不知道你注意過沒有,數組能夠嵌套在標籤內部,正常渲染。
function NumberList(props) { const numbers = [1,2,3,4,5]; // listItems是數組numbers經過map返回的,本質也是個數組。 const listItems = numbers.map((number) => <li>{number}</li> ); return ( <ul> // 能夠替換成 [ <li>1</li>, <li>2</li>, .....] {listItems} </ul> ); }
如上所示,標籤內部的數組是能夠正確渲染的,那麼就有如下的寫法:
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() 執行結果是數組 return ( <ul>{ this.renderItem() }</ul> ) }