標籤:
最近的項目中開發中都是用react,其中有用到react去操縱表單。然後自己就在每個表單元素中添加 ref, 然後再像jquery操作dom一樣去操縱這個ref,
代碼如下:
首先我在每個表單元素那裡都加了ref
然後再像操作dom一樣動作表單
整個過程看起來即累贅,又感覺很怪。這樣你還不如直接用jqurey來操作dom.
在這裡,想補充一下 react 中的ref到底為何物
ref
屬性可以是一個回呼函數,而不是一個名字。這個回呼函數在組件安裝後立即執行。被引用的組件作為一個參數傳遞,且回呼函數可以立即使用這個組件,或儲存供以後使用(或實現這兩種行為)。
它與把 ref
屬性分配給從 render
返回來的東西一樣簡單.
完成的樣本
var App = React.createClass({ getInitialState: function() { return {userInput: ‘‘}; }, handleChange: function(e) { this.setState({userInput: e.target.value}); }, clearAndFocusInput: function() { // Clear the input this.setState({userInput: ‘‘}, function() { // This code executes after the component is re-rendered React.findDOMNode(this.refs.theInput).focus(); // Boom! Focused! }); }, render: function() { return ( <div> <div onClick={this.clearAndFocusInput}> Click to Focus and Reset </div> <input ref="theInput" value={this.state.userInput} onChange={this.handleChange} /> </div> ); } });
在這個例子中,render 函數返回 <input/ >
執行個體的描述。但真正的執行個體是通過 this.refs.theInput
訪問的。只要帶有 ref =“theInput”
的子組件從 render 返回,this.refs.theInput
就會訪問適當的執行個體。這甚至能在更高的層級(non-DOM)組件中實現,如 <Typeahead ref = " myTypeahead " / >
。
總結
向一個特定的子執行個體發送訊息,Refs 是一個很好的方式,而通過流動式接收 Reactive 的 props
和 state
的方式可能是不方便的。然而,對於你的應用程式中的流動資料來說,refs 應該不是你的首選抽象特性。預設情況下,為用例使用 Reactive 資料流並儲存 ref
s 本來就是無功無過的。
好處:
- 你可以在組件類中定義任何公用方法(如在 Typeahead 中的複位方法),並通過 refs(如
this.refs.myTypeahead.reset()
)調用這些公用方法。
- 執行 DOM 測量幾乎總是需要接觸“本地”組件,如
<input/ >
,並通過 React.findDOMNode(this.refs.myInput)
訪問它的底層 DOM 節點。Refs 是可行的可靠的方法之一。
- refs 自動為你 book-kept!如果子組件被摧毀,那麼它的 ref 也被摧毀了。在這裡不必擔心記憶體(除非你為保留自己的 reference 做了一些瘋狂的事)。
注意事項:
- 永遠不要訪問組件的 render 方法內部的 refs——或任何組件的 render 方法正在 call satck 中運行時,也不要訪問 refs。
- 如果你想儲存 Google Closure Compiler Crushing 的彈性,確保永遠不要訪問作為字串被指定的屬性。這意味著如果你的 ref 被定義為
ref =“myRefString”
,你必須使用 this.refs[‘myRefString‘]
來訪問。
- 如果你還沒有用 React 給幾個應用程式編程,那麼你通常首先會傾向於嘗試使用 refs 來“讓事情發生”在你的應用程式中。如果是這樣的話,花點時間,更為謹慎的思考一下
state
應該屬於組件階層的什麼位置。通常情況下,你會清楚地發現,“擁有”那個 state 的適當的位置是更高的階層中。把 state 放置在那裡通常可以消除任何想要使用 ref
來“讓事情發生”的現象——相反,資料流通常會實現你的目標。
上面的介紹參考:http://wiki.jikexueyuan.com/project/react/more-about-refs.html
看的不是很懂。不過總結出,如果我像我上面那樣去操作一大丟的表單的話,會影響資料流的執行
所以我將My Code改為如下:
首先,在初始狀態,設定表單的值
然後,將表單的ref值去掉,而是動態來給它賦值
再之後, 給每個表單添加這些時間,讓它輸入框每次變化的時候,都更新表單value對應的state。下面是每個表單對應的事件
最後,將這些事件添加到表單的onChange中
通過這樣的修改,每次我的輸入框發生變化時,表單value對應的state就會更新,從而達到操縱表單的效果。
結合著ajax的話,我們只需要擷取每個表單的當前的state就行。比如,我要擷取price這個元素的值,我只需要var priceValue=this.state.price既可。
而不需要去操作一系列的dom。因為是處於示範,所以每個表單的函數我就沒有去封裝了。共用一套看起來會好看點
如果有更好的辦法,望多多指教!
React動作表單