在 React 社區,遇到最多的其中一個問題是「不同組件之間如何相互通訊」。
在網上搜索了一些答案之後,早晚會有人提到 Flux,隨後問題來了:「怎麼用Flux解決通訊問題?Flux是必須的嗎?」。
有時候 Flux 能解決組件通訊的問題,不過它不是必須的。在本文中我們將介紹幾種通訊方式,這裡沒有用到 Flux。
首先要說明要選擇哪種通訊策略完全取決於要通訊的組件之間的關係。
下表展示了這幾種通訊方式,你可以根據項目實際情況選擇對應的方式。
1.Props
Props 是目前為止最常用的方式,用於在組件之間傳遞信息。用 props 可以把數據從父組件傳遞到它的子組件中。
Props 是 React 的核心功能,也是 React 的基礎知識。如果還不熟悉的話,需要訪問官網閱讀相關文檔。
2.實例方法
在父組件中可以用 refs 引用子組件,之後就可以調用子組件的實例方法了。這是另一種從父組件訪問子組件的方式。
3.回調函數
方法 1 和 2 介紹了如何把數據從父組件傳給子組件,如果反過來傳值如何做呢?如何把數據從子組件傳給它的父組件?
最簡單的方式是在父組件中傳遞一個函數給子組件,子組件可以使用這個函數來把數據傳給它的父組件。
在父組件中可以這樣把一個函數作為屬性傳給子組件,例如:
然後子組件可以這樣調用這個函數:
最後不要忘記在子組件的 propTypes 中聲明這個函數:
4.事件冒泡
事件冒泡並非 React 的概念,而是瀏覽器中 DOM 的事件機制。和回調函數類似,它也可以把數據從子組件發送到父組件。
當你想在父組件中捕獲來自子組件中的 DOM 事件時,可以採用此方法。
在上述代碼中,點擊子組件中的 div 元素之後,在瀏覽器的控制臺可以看到輸出了這個 div 元素。這是因為我們在父組件中定義的事件監聽器成功監聽到了來自子組件冒泡上來的 click 事件。
5.父組件
如果兩個需要通訊的組件,它們擁有共同的父級組件,我們可以使用上述的策略組合,只是需要使用父級組件作為溝通的媒介,把數據作為父組件的 state 和方法來定義。
6.觀察者模式
觀察者模式是一種軟體設計模式,一個對象可以在需要時發送數據到多個其他對象。
這種方式適用於所有組件,不需要時父子組件或者平級組件。
一般的做法是在 componentDidMount() 裡訂閱事件,在 componentWillUnmount() 裡取消訂閱,然後在接收事件時調用 setState() 方法。
網上有許多庫實現了觀察者模式,例如 PubSubJS,EventEmitter等。
7.全局變量
一般來說,使用全局變量不是最佳實踐。不過它很實用,可以幫你節省大量時間。如果謹慎使用是完全沒問題的。
建議定義全局變量時用 window. 明確定義,以後管理維護時會更加方便。在一個組件的生命周期或者事件監聽器裡設置 window.x 全局變量,然後在其他組件裡就可以用 window.x 讀取它了。
8.Context
Context 和 props 類似,不過它不是為單個子組件傳遞數據,它可以為整個子樹提供數據。
Context 只可以在樹中向下傳遞數據(父組件到子樹)。可以配合回調函數來向上傳遞數據(子樹到父組件)。
典型的可以使用 Context 的場景有在組件樹中傳遞已登錄的用戶信息,首選語言,或主題。不過需要注意不要濫用它,因為那樣會讓組件的重用變得更加困難。
更多信息可以訪問 React 官方文檔。