生活随笔
收集整理的這篇文章主要介紹了
react 实现数据双向绑定
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
首先從沒有使用mixin的例子引入
?
[javascript]?view plaincopy print?
var?BindingExample?=?React.createClass({??????????????getInitialState:?function()?{??????????????????return?{??????????????????????text:?''??????????????????}??????????????},??????????????handleChange:?function(event)?{??????????????????this.setState({text:?event.target.value})??????????????},??????????????render:?function()?{??????????????????return?<div>??????????????????????<input?type="text"?placeholder="請輸入內容"?onChange={this.handleChange}?/>??????????????????????<p>{this.state.text}</p>??????????????????</div>??????????????}??????????})??React.render(<BindingExample></BindingExample>,?document.body);?? ?
?
這個例子大家都很熟悉,當input框發生改變的時候,去調用handleChange方法,然后通過setState重新render P標簽中的數據
?
接下來引入使用mixin的一個例子,沒有使用官方的方法
?
[javascript]?view plaincopy print?
var?BindingChange=?{????????????????handleChange:?function(key)?{????????????????????var?that?=?this,??????????????????????newState?=?{};????????????????????return?function(e)?{????????????????????????newState[key]?=?e.target.value;??????????????????????that.setState(newState);????????????????????}????????????????}????????????}????????????var?BindingExample1?=?React.createClass({????????????????mixins:?[BindingChange],????????????????getInitialState:?function()?{??????????????????return?{??????????????????????text:?"",??????????????????????comment:?""??????????????????}??????????????},??????????????render:?function()?{??????????????????return?(??????????????????????<div>???????????????????????????<input?type="text"?placeholder="請輸入內容"?onChange={this.handleChange('text').bind(this)}?/>???????????????????????????????????<textarea?onChange={this.handleChange('comment').bind(this)}></textarea>???????????????????????????????????????<p>{this.state.text}</p>???????????????????????????????????????<p>{this.state.comment}</p>??????????????????????</div>??????????????????);??????????????}????????????})??????????React.render(<BindingExample1?/>,document.body);??
來分析一下這個例子
?
首先看BindingExample中的render,仔細觀察一下實際上和例子一沒有什么區別,只是在onChange處理的函數上綁定了上下文,還在在函數里面傳了一個值(key)
這個key和state中對應的key值要相同,如例子中input改變的時候是修改state中的"text"這個狀態,所以傳入"text"。
然后再看BindingExample中的mixins,把BindingChange引用了進來,在引用之后,BindingChange中的東西就會變成BindingExample的東西
所以onChange那里進行bind之后,BindingChange的this指針指向了BindingExample,而不是window。
?
接著看一下BindingChange。先定義了一個that來保存當前的this,接下里定義了一個對象
為什么要定義一個對象呢。
可以發現,React中setState要修改的狀態名字不是一個字符串,也不能解析變量。如果假如onChange事件中傳入的key為"text",直接這樣修改 setState({key:event.target.value}) 實際上并沒有修改text的值,然是去修改了key的值,然而我們并沒有在實際的代碼中存在key這個狀態,所以并不會發生改變。
所以在return的那個函數中newState[key] = e.target.value,這個時候key就可以解析成了text,并且進行了賦值,然后將該對象傳入setState中,text這個狀態得以改變。
當然,假如傳入的是comment這個值,那么這個key實際上就是comment,然后改變的是comment的狀態
?
讀到這里大家可能都發現了,mixin做的就是把一些相同的東西抽離出來,就像這個onChange事件,如果沒用mixin的話,可能就要寫onChange1和onChange2。實際上就像方法的封裝一下。當然也有不好的地方,就是查找這個方法的時候可能不會一下子找到。
?
最后引入官方的例子
?
[javascript]?view plaincopy print?
var?BindingExample2?=?React.createClass({??????mixins:?[React.addons.LinkedStateMixin],??????getInitialState:?function()?{??????????return?{??????????????text:?"",??????????????comment:?""??????????}??????},??????render:?function()?{??????????return?(??????????????<div>??????????????????<input?type="text"?placeholder="請輸入內容"?valueLink={this.linkState('text')}?/>???????????????????????????????????<textarea?valueLink={this.linkState('comment')}></textarea>???????????????????????????????????<p>{this.state.text}</p>???????????????????????????????????<p>{this.state.comment}</p>??????????????</div>??????????);??????}???});???React.render(<BindingExample2?/>,document.body);?? 對比例子2,我們發現在mixin中使用了React.addons.LinkedStateMixin,這個就是官方封裝好的自己的雙向綁定的方法
?
再往下讀下去發現onChange事件變成了valueLink,然后使用了方法linkState,而傳入的值依舊是這個input想要改變的狀態的名字。
?
我們來看一下官方的這個方法是怎么封裝的
?
[javascript]?view plaincopy print?
var?ReactLink?=?_dereq_(75);???????var?ReactStateSetters?=?_dereq_(94);?????????var?LinkedStateMixin?=?{???????????linkState:?function(key)?{???????????????return?new?ReactLink(???????????????????this.state[key],???????????????????ReactStateSetters.createStateKeySetter(this,?key)???????????????);???????????}???????};?????????module.exports?=?LinkedStateMixin;?? 這個就是方法封裝的mixin的LinkedStateMixin方法
?
官方是這么解釋的
ReactLink encapsulates a common pattern in which a component wants to modify a prop received from its parent.
ReactLink封裝了一個需要從父級獲取值并且修改的一個公有的模式。(實際上就是綁定上下文環境,然后函數的封裝)
?
然后我們去查看ReactStateSetters.createStateKeySetter這個方法是這樣寫的
?
[javascript]?view plaincopy print?
createStateKeySetter:?function(component,?key)?{??????var?cache?=?component.__keySetters?||?(component.__keySetters?=?{});????return?cache[key]?||?(cache[key]?=?createStateKeySetter(component,?key));??}?? 傳入上下文環境,傳入要修改的狀態的名字。看到cache,大家也能明白這是緩存的意思,判斷是否有這個狀態,有的話直接復制,并返回。沒有的話就創建一個對象,然后進入(cache[key] = createStateKeySetter(component, key))這個方法中
?
?
然后繼續找到了createStateKeySetter,他是這個樣子的
?
[javascript]?view plaincopy print?
function?createStateKeySetter(component,?key)?{????var?partialState?=?{};????return?function?stateKeySetter(value)?{??????partialState[key]?=?value;??????component.setState(partialState);????};??}?? 繼續傳入上下文環境,傳入要修改的狀態的名字。然后往下讀,是不是突然發現很熟悉,這個不就是和例子二中的handleChange是一模一樣的。
?
?
此篇博文到此就結束了。
?
轉載于:https://www.cnblogs.com/rubyxie/articles/5920096.html
總結
以上是生活随笔為你收集整理的react 实现数据双向绑定的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。