最近的項目中開發中都是用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
看的不是很懂。不過總結出,如果我像我上面那樣去操作一大丟的表單的話,會影響數據流的執行
所以我將我的代碼改為如下:
首先,在初始狀態,設置表單的值
然后,將表單的ref值去掉,而是動態的來給它賦值
再之后, 給每個表單添加這些時間,讓它輸入框每次變化的時候,都更新表單value對應的state。下面是每個表單對應的事件
最后,將這些事件添加到表單的onChange中
通過這樣的修改,每次我的輸入框發生變化時,表單value對應的state就會更新,從而達到操縱表單的效果。
結合着ajax的話,我們只需要獲取每個表單的當前的state就行。比如,我要獲取price這個元素的值,我只需要var priceValue=this.state.price既可。
而不需要去操作一系列的dom。因為是處於演示,所以每個表單的函數我就沒有去封裝了。共用一套看起來會好看點
如果有更好的辦法,望多多指教!