一、什麼是雙向綁定、爲何須要雙向綁定?
本人是先入坑的vue,因此在開發時已經習慣了vue的自動雙向綁定。javascript
什麼是雙向綁定呢?html
在沒有前端框架以前的開發時光中,咱們都是直接操做頁面的DOM元素(element)的。將某個變量賦值到某個頁面元素時都是一次性的操做,在此以後變量值的修改並不會影響頁面元素的內容變化;而頁面元素(好比input框)的內容變動之後,也不會使對應變量的值發生變化,咱們須要經過document.getElementById()
的方法獲取到頁面元素,而後再根據元素對象的value
獲取變化之後的值再手動處理。前端
在vue中,框架已經幫咱們自動實現了雙向綁定,任何一方(哪怕是頁面上純顯示的)也會自動變化。(如下代碼中,變量name
的變化會直接反應到input框中,而input框中值得修改也會反向引發name
變量的值變化。)vue
<!-- Vue中一個最簡單的雙向綁定示例 --> <template> <div> <el-input v-model=「name」 /> </div> </template> <script> export default { data() { return { name: "", } }, } </script>
而到了react,發現並無雙向綁定的功能,有點懊糟。java
NameShow.js import React from 'react'; class NameShow extends React.Component { myName = "" // 定義myName變量 render() { return ( <div> {/*嘗試將myName變量綁定到input框上*/} <input value={this.myName}/> {/*獲取myName,並直接顯示在頁面上*/} <div>My Name Is {this.myName}</div> </div> ) } } export default NameShow
將以上組件引入APP中並添加到頁面上啓動,發現不只沒法雙向綁定,甚至連修改input框的內容都沒有任何反應,並且控制檯有警告顯示。大概的意思是value是隻讀的,值的修改必須經過onChange事件來修改。react
因此添加一個onChange
事件的handle方法handleChange
之後再次啓動。前端框架
NameShow.js import React from 'react'; class NameShow extends React.Component { myName = "" // 定義myName變量 handleChange = (event) => { // 此處需使用箭頭函數,不然方法中的this將會識別爲undefined console.log(event.target.value) this.myName = event.target.value } render() { return ( <div> {/*嘗試將myName變量綁定到input框上*/} <input value={this.myName} onChange={this.handleChange}/> {/*獲取myName,並直接顯示在頁面上*/} <div>My Name Is {this.myName}</div> </div> ) } } export default NameShow
在輸入框中輸入內容之後,發現控制檯有反應,正常拿到了修改之後的值,可是輸入框和下面顯示的內容卻依舊沒有變化。閉包
二、React不支持雙向綁定?非也
react並非不支持雙向綁定,而是雙向綁定須要咱們本身來實現。這時候就是react中的一個重要概念登場了——React State。框架
在菜鳥教程中的解釋是這樣的:React 把組件當作是一個狀態機(State Machines)。經過與用戶的交互,實現不一樣狀態,而後渲染 UI,讓用戶界面和數據保持一致。函數
如今回到上面那個例子,進行一下改造,由使用類成員變量myName
改成使用state
中的myName
變量。
NameShow2.js import React from 'react'; class NameShow2 extends React.Component { constructor(props) { super(props); this.state = { // 注意1:此處需先對state進行初始化,否則編譯會報錯 myName: "" // 注意2:此處須要將變量在state中進行定義,不然會報警告 } } handleChange = (event) => { console.log(event.target.value) // this.state.myName = event.target.value // 注意3:此處直接賦值是無效的,必定要使用this的setState方法 this.setState( {myName: event.target.value} ) } render() { return ( <div> {/*嘗試將myName變量綁定到input框上*/} <input value={this.state.myName} onChange={this.handleChange}/> {/*獲取myName,並直接顯示在頁面上*/} <div>My Name Is {this.state.myName}</div> </div> ) } } export default NameShow2
將以上組件引入APP中並添加到頁面上啓動,並在input框填入內容,發現下面的顯示也同步改變了,而且控制檯也有輸出。
到此,一個簡單的react雙向數據綁定的流程就完成了。
三、小結
-
在react中要實現數據的雙向綁定,須要經過state來實現,
根據菜鳥解釋,react將每一個組件都定義爲狀態機,經過state來改變和控制組件的狀態。
-
使用state以前須要先初始化,而且在state中定義所須要用到的變量,
這個相似於vue中使用前先要在
data
部分定義變量。(通常使用時能夠不用預先定義變量,只有在變量綁定對象爲
<input>
<textarea>
<select>
時才須要,具體內容能夠參考react官網相關解釋。) -
直接對state進行賦值是無效的,須要使用
setState
方法來賦值,這樣才能觸發狀態的改變,從而達到值傳遞的效果。
另外補充一點,在上述兩個例子中都將handleChange
方法都以箭頭函數的方式進行定義,這是因爲js的閉包致使的。
若是想將handleChange
定義爲普通方法,能夠在構造函數中將this
對象綁定到handleChange
方法
constructor(props) { super(props); this.state = { myName: "" } this.handleChange = this.handleChange.bind(this) // 將`this`對象綁定到`handleChange`方法 }