以下內容均為個人理解。
1.state:
在react中,state可以看成管理頁面狀態的集合(實則一個對象而已),庫里面的成員均為頁面渲染變量,整個頁面為一個狀態機,當state發生變化時,頁面會重新渲染,頁面隨state變化而變化。
2.state如何正確使用:
const eventsArr = [ 'handleText1Change', 'handleText2Change', 'handleText3Change' ]; const EmptyString = ""; class Dome extends React.Component { constructor(props) { super(props); this.state = { text1: EmptyString, text2: EmptyString, text3: EmptyString, flag: true }; this.setBindFunc(); }; setBindFunc() { eventsArr.forEach(ev => { this[ev] = this[ev].bind(this); }) }; handleText1Change(e) { this.setState({ text1: e.target.value }); }; handleText2Change(e) { this.state.text2 = e.target.value; this.setState({}); }; handleText3Change(e) { this.setState({ text3: e.tarege.value }, () => { this.state.flag = false; }) }; render() { return <div> <input type='text' value={this.state.text1} onChange={this.handleText1Change} /> <input type='text' value={this.state.text2} onChange={this.handleText2Change} /> <input type='text' value={this.state.text3} onChange={this.handleText3Change} /> </div> }; };
state控制頁面渲染,但是只給state賦值是不會導致頁面刷新的,只有調用this.setState({})方法后才會執行render方法,最后導致頁面重新渲染。
第一種寫法:
this.setState({text1: e.target.value})為最常規的寫法,執行完此方法之后會執行render方法,刷新state中的text1值。但是這里有個問題就是this.setState({})本身作為異步函數,賦值與渲染上會有先后問題,
在執行this.setState({text1: e.target.value})這個方法是,實際上this.state.text1的值沒有改變。當走到render里面的時候this.state.text1的值才會發生改變,render內原則不可以寫過多的賦值邏輯,如何解決呢產生方法二。
第二種寫法:
this.state.text2 = e.target.value; 這種賦值可以直接改變this.state.text2的值,然后調用this.setState({})重新渲染頁面,這種方式不會存在異步問題(只要調用this.setState({}),render函數是必然會走的,除非使用
第三種寫法:
this.setState({},()=>{})這種賦值與第一種一樣,主要側重在回調函數上,回調函數是在執行完render后執行,回調函數內可以寫邏輯,我們拿個簡單的賦值舉例。這種方式可以控制組件渲染的先后順序。
1.props:
props是組件之間傳遞數據的媒介。那么在使用props時應該注意哪些。
1 const 2 eventsArr = [ 3 'handleText1Change', 4 'handleText2Change', 5 'handleText3Change', 6 'handleText4Change' 7 ]; 8 9 const EmptyString = ""; 10 11 class Dome extends React.Component { 12 constructor(props) { 13 super(props); 14 this.state = { 15 text1: EmptyString, 16 text2: EmptyString, 17 text3: EmptyString, 18 text4: EmptyString, 19 obj: { 20 value: EmptyString 21 }, 22 flag: true 23 }; 24 this.setBindFunc(); 25 }; 26 27 setBindFunc() { 28 eventsArr.forEach(ev => { 29 this[ev] = this[ev].bind(this); 30 }) 31 }; 32 33 handleText1Change(e) { 34 this.setState({ 35 text1: e.target.value 36 }); 37 }; 38 39 handleText2Change(e) { 40 this.state.text2 = e.target.value; 41 this.setState({}); 42 }; 43 44 handleText3Change(e) { 45 this.setState({ 46 text3: e.tarege.value 47 }, () => { 48 this.state.flag = false; 49 }) 50 }; 51 52 handleText4Change(oldValue, newValue) { 53 this.state.text4 = newValue; 54 }; 55 56 render() { 57 return <div> 58 <input type='text' value={this.state.text1} onChange={this.handleText1Change} /> 59 <input type='text' value={this.state.text2} onChange={this.handleText2Change} /> 60 <input type='text' value={this.state.text3} onChange={this.handleText3Change} /> 61 <DomeChildren 62 text4={this.state.text4} 63 obj={this.state.obj} 64 handleText4Change={this.handleText4Change} 65 /> 66 </div> 67 }; 68 }; 69 70 const 71 Constants = { 72 Click: 'Click' 73 }; 74 75 class DomeChildren extends React.Component() { 76 constructor(props) { 77 super(props); 78 this.state = { 79 text: this.props.text4, 80 obj: this.props.obj 81 }; 82 }; 83 84 handleText4Change(e) { 85 let 86 oldValue = this.state.text, 87 newValue = e.target.value; 88 this.state.text = newValue; 89 this.setState({}); 90 this.props.handleText4Change(oldValue, newValue); 91 }; 92 93 handleClick() { 94 //僅做例子用 95 this.props.text4 = "Dqhan"; 96 this.props.obj.value = 10086; 97 } 98 99 render() { 100 return <div> 101 <input type='text' value={this.state.text} handleText4Change={this.handleText4Change.bind(this)} /> 102 <div onClick={this.handleClick.bind(this)}>{Constants.Click}</div> 103 </div>; 104 }; 105 };
首先props是用於組件之間傳遞信息的,比如父組件Dome傳遞給子組件DomeChildren了text4,obj跟一個方法handleText4Change,這里我們達到了props作用的目的,當子組件內執行handleText4Change,改變了DemoChildren里面的text值同時渲染該組件,這里沒有影響到Demo,同時DomeChildren將oldValue與newValue通過傳遞的handleText4Change方法暴露給了Demo,達到了父給子傳遞,子給父傳遞的,子組件渲染沒有影響到父級的目的,我理解這是最正確的傳遞方式以及組件之間的關系。當執行handleClick方法時,可以看到代碼執行this.props.text4="Dqhan"時react會報錯,這說明props是不可以改變的,但是this.props.obj.value = 10086沒有報錯,很明顯,因為obj是對象,這里我理解為,只要物理地址沒有變,react就會認為是props沒有改變,不然很多地方用到了數組就沒招了。總結:props中簡單類型不能改變,引用類型內部的屬性可以改變。
補充一下,創建組件時用的ES6語法class關鍵字,熟悉服務器語言的都知道,一個類是通常情況下實例化然后才能使用的(除工具類等),而react中<Demo />便是實例化這個組件(react自己封裝的)得出一個對象。