標籤:

React 組件如何與其他框架進行數據交流?

比如一個 jQuery 的表單頁面,其中有一些 input 類的組件要替換成 React。最後點擊按鈕之後用 jQuery 拿到這些 React 的 input 組件中的 value,進行校驗並發送請求。

jQuery 如何在 React 外面拿到 React 組件當前內部的 State?在 setState 的時候同步設置更新一個全局變數?

==

COIN 的方法可以較好的滿足,推薦。


說真的我比較討厭拿 react 跟其他方案混用,組件內用 jQuery 作為 dom 操作的補充還好一些,但是給 react 提供跨組件的數據通訊方式,本身就在破壞 react 的 pure render 的基礎假設。我的理解是沒有靠譜的辦法。當然如果一定要用,事件機制可以試一下。


------------------------- 更新 -----------------------------

先確立一個觀點:組件是不應該直接由外部操作其內部的屬性的,如果要操作,應該通過組件組件提供介面。

題主這樣的需求,我覺得沒必要引入事件系統,一個事件系統再精簡也要幾十行代碼,三四個介面(on,off,emit,all...)。這類小型的組件,可以直接寫回調,比如

&

也可以提供一個介面,用來取出內部值:

var input = ReactDOM.render(&, mountNode);
input.getCurrentValue()

反正不應該直接 `input.state.currentValue`。

--------------- 嚴肅的割一下 ---------------------

下面扯扯自己項目中react和anguar結合遇到的一些問題,有興趣的可以往下看~

因我們有多個項目同時進行,因歷史原因,前端團隊的技術儲備全部是anguar,沒有一個react。

但有一個項目是要依賴於伺服器渲染,這是前提。

所以在寫組件庫的時候,就決定用react(當時也沒得選,能做伺服器渲染的就這貨一個)來寫組件,angular寫業務邏輯。

想法是很豐滿的,不就是通訊嘛,看了react官方文檔之後,覺得store分分鐘上手。

果斷的決定了react寫組件,angular調用react組件的模式。

編譯和構建依賴於gulp和webpack,沒什麼問題,也沒什麼好說的。

但是我錯誤估計了兩個問題:

  1. 團隊成員的接受力問題。
  2. 業務的複雜度。

第一點是因為react真的超級簡單啊,媽蛋就10多個api,還有個jsx,看文檔也就是一天的事情。然而我們團隊買了5本書,書名就不說了...今年1月分就發給前端人員了,到今天(5月4號),沒有一個人能完整的寫一個TodoList出來...都說業務忙,沒時間看...,我封裝了十多個基礎組件,文檔齊備,demo寫完。在實際運用中依然要坐在旁邊一步一步的說才能正確使用。

在這個moment,我是羨慕全是上進的孩子的團隊....

擦擦淚繼續。

第二點,因為最開始寫組件的時候是依賴於靜態設計稿和原型,沒有交互文檔,所以沒有正確預估到在實際項目中的交互的複雜程度,再加上團隊成員對react不熟悉,有文檔也不看,更不用說基於基礎組件去封裝業務組件了。造成的結果就是一個DropDown最開始是這樣寫的

&

後面html結構變化(靜態頁不是同一人所寫,看起來一樣內部html結構完全不相同...這...),補了兩三個DropDown的衍變組件後,發現這是個大坑,填不滿,後面就改成了這樣。

&

所有的html結構全部通過自定義函數返回,DropDown本身只提供彈出、關閉、onSelect等最基礎的東西,UI統一的目標基本失敗,只有動畫是統一的了...因為DropDown內部由Animate組件包裹了.....

我想靜靜,你卻不是靜靜.....

再之後,要和angular結合。angular本身是通過$scope來交互的,如果組件所有的值都需要綁定一個回調或者一個事件傳播到angular,估計我會被寫業務的同事砍死。

後面想了個辦法,react只提供基礎組件的功能,主要目的是為了實現各系統上交互上的統一。這樣我們改變了原來的想法(一切皆是組件),因為這真的做不到... 團隊技術儲備、設計和需求的穩定性、每個成員的個人因素影響等皆是原因。再加上我們沒有一個人專門去維護組件庫,比如我...老夫也是要寫業務的(上線時間緊...),好了扯遠了,說回只提供基礎組件功能。

比如一個Dialog,正常的組件可能是這樣的

&

} /&>

render 一下就冒出來一個華麗的框框...

但是我們不是這樣的....我們是這樣的....

var onMount = function(wrap, inst){
var node = $compile(tpl)($scope)[0]
wrap.appendChild(node)
// tpl 中綁定了$scope上的函數...
}
var dialog = ReactDOM.render(&

, mountNode)
dialog.show()
dialog.hide()
dialog.unmount()
....

這就是angular與react的華(bei)麗(ai)結合...

react只提供一個容器,angular編譯一個模板之後再塞到容器中(感謝react提供了this.refs的屬性,讓我可以取到原生DOM節點...)。

我參考過ant.design的組件props設計以及amazonUi的react組件設計,發現其開放出來的成品都基於一個前提:UI已定,交互已定。

這對一個穩定的產品而言是可行的,然而對於一個需求待定,交互待定,趕著上線的項目,是比較痛苦的。

說下我現在的工作日常:

哎哎,xx(老夫的大名),過來看一下,這個怎麼弄呢。

xx,我有個問題呢,想問一下呢(一個萌妹子)

xx,好難啊,好複雜啊,你過來看一下

xx,要添加一個Importable組件喲,我這裡要用。

-- 老夫:這個用DropDown封裝一下就是Importable了哦。

-- 可是好麻煩啊,我看到react就頭疼。

-- 老夫:哦,騷等,我寫好了上傳到gitlab...

xx,過來看看,伺服器怎麼不可用了...

xx,過來看看,mock數據不對呀...

-- 老夫心裡:不對你特么的應該問後端呀...

-- 老夫身體:哦,我來了

上周一周,我就寫了一上午業務代碼。

------------------------------------------------------------------------

總結一下:

  1. 首先問題在我,我在選型的時候沒有考慮到這些問題,後面的所有問題都在於react組件和angular交互上。
  2. 團隊的技術儲備和學習能力真的很重要,沒有考慮這一點就貿然去猜測團隊的水平,這是不對的。
  3. 在UI和交互未定的情況下,所有的組件庫都應保留最大限度的可定製性,比如content可以由函數生成,而不是寫死Html結構。在這個基礎上,在頁面已出、html結構已定時,可以自由的封裝業務組件,豐富基礎組件庫。
  4. 一個團隊要有一兩個獨擋一面的,不用寫太多業務代碼的同學。
  5. html結構,真的很難寫好,能招一到一個css極其牛叉的人的團隊,都是幸運的。

-------------------------------------------------------------------------

我想我媽了....

------------------------- 以下為占坑文字 -----------------------------

先佔坑,後面來答。

我現在的項目是angular加react混搭。。。


這種情況應該用Redux吧,這樣React之外的組件要什麼數據自己去store取就好了.

如果只是過度版本我感覺沒必要強行上React吧.


瀉藥,沒用過react。。。但是我的直覺是你缺個廣播系統。


瀉藥。

把組件內部的狀態暴露給 jQuery ,這樣做倒也不是不行,在剛用 React 的時候我為了 debug 就會把組件綁到全局變數上,方便查看它內部的一些細節。但把這種做法我從直覺上還是排斥的。

React 的重要的特性是組件和重用、單向數據流,如果把一個組件的 state 暴露出去,會破壞這些特性,本該寫在一個組件里的代碼被分割成兩部分,沒法重用,且不好讀也不好維護。

在 React 文檔中有提到跟其他庫交互時,應該把這些庫的操作封裝在 React 組件內部,並且用 React 組件的 mount/unmount 機制來控制這些庫實例的初始化和卸載操作。

所以與其把 state 暴露出去,不如寫一個 validator 組件,把 jQuery 操作封裝成一個單獨的組件。


把react封裝在jquery插件內部,通過props傳入回調,達到向外通知的目的,之前寫的文章,裡面有介紹

https://github.com/lizzz0523/mvc-mode-seed/blob/master/README.md

不贊同那些說不要混用jquery和react的知友,技術不是烏托邦,沒用所謂理想主義,應該根據項目的情況來做架構,這才是上道


大概看了下,也就是缺一個全局事件機制了,或者說廣播訂閱。我之前寫react遇到過組件間通信問題,特別是不同 router下面的。後來就是用這個解決的。

GitHub - hustcc/onfire.js: onfire.js is a simple events dispatcher subscribe / publish library (just 0.9kb). async, simple and usefull.


用vue沒用過react 不過根據redux之於react相當於vuex之於vue這句話來看的話 redux就適合用在這種場景下 一個應用維護一個狀態 組件需要數據去store取


用flux之類的維護一個store,相對於全局變數清晰一點點,既然是過渡版本就將就一下吧。


React搞一個public方法getValue,然後拿到React對象 調用 getValue方法 不就可以了?於大師?


react和jquery用在一起真的大丈夫么?


推薦閱讀:

【譯】Redux + React 應用程序架構的 3 條規範(內附實例)
[上海] 招前端,移動端,小程序開發(多圖)
React 源碼剖析系列 - 不可思議的 react diff
Vue2技術棧歸納與精粹

TAG:jQuery | React |