国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

玩轉 React(七)- 組件之間的數據共享

Gu_Yan / 2116人閱讀

摘要:函數屬性或者說事件在組件之間通信過程中是必不可少的,但是切莫讓它影響了大家對單向數據流這一概念的理解。這應該屬于一種的使用方式,而且這樣做有悖單向數據流原則。

上一篇文章 玩轉 React(六)- 處理事件 介紹了在 React 中如何處理用戶事件,以及 React 事件機制與原生 DOM 事件的差異和注意的問題,同時也介紹了事件處理函數中 this 的指向問題以及處理的幾種方式及其優缺點。

大家在閱讀的過程中有任何為題可以給我留言,同時歡迎大家加入玩轉 React 微信群,我的微信號是 leobaba88,先加我好友,驗證信息:玩轉 React,然后我會拉你進群。

今天這篇文章要講的內容是關于多個組件之間如何共享數據,或者說是如何通信的。只有掌握了正確的組件之間通信的方式,才能在開發交互復雜的前端應用時做到游刃有余,所謂正確的方式也就是符合 React 設計理念的方式。使用一個框架時,一定要遵從框架的最佳實踐,人家框架是這樣設計的,你偏要那樣來用,用得不爽還要噴其不好用,那就不應該了。

內容摘要

React 中的數據是單向自頂向下傳遞的。

單向數據流與雙向綁定的差異。

最符合 React 理念的組件之間共享數據的方式。

數據唯一來源原則。

一些不好的方式。

先跟 Redux 打個招呼。

其他一些關于組件間通信的內容(context、ref)。

組件之間通信的最佳方式

現在我們就來探討下,什么樣的方式才是 React 中組件之間通信的正確方式。

在前面的文章中,我們有說過,React 之所以能勝任大型復雜前端項目的開發,是因為其 單向數據流 這一重要特性,單向數據流能讓視圖更新邏輯變得簡單,從原始的對 DOM 操作變為對數據操作,簡單了就容易維護。

React 組件中數據的流動方向是自頂向下的,也就是說在組件樹中,數據只能從父組件以屬性的方式傳遞到子組件,父組件的數據可能是其接收到的屬性,也可能是自身的內部狀態。

有些同學這里可能會比較困惑,說子組件明明可以通過一個函數屬性將數據傳遞給父組件呀。好多同學甚至因此搞不明白單向數據流和雙向綁定的差異。其實換個角度考慮一下就清楚很多了,既然“數據傳遞”這個詞區分度不夠大,那就換個區分度比較大的說法。我們可以這樣理解,函數屬性是子組件用來通知父組件發生了什么,它更像是子組件觸發的一個事件,父組件可以依據業務邏輯來選擇如何處理這個事件,它可以更新數據后重新傳遞給子組件,也可以置之不理。

函數屬性(或者說事件)在組件之間通信過程中是必不可少的,但是切莫讓它影響了大家對單向數據流這一概念的理解。

數據雙向綁定不一樣,在雙向綁定中父組件將數據傳遞給子組件,子組件修改數據后會將數據回傳同步給父組件,父組件是無條件接受的。這里就不過多去說哪個好哪個差了,有興趣的同學可以自己去體會,懶一點的就堅持學習 React 吧。

狀態提升(Lifting State Up)

既然 React 中的數據是單向自頂向下傳遞的,那么符合 React 這一特性的組件通信方式就顯而易見了。

狀態提升的意思是,當組件 A 需要依賴另外一個組件 B 的內部狀態,而他們又不是父子關系時,需要將組件 B 的內部狀態提升到他們公共的祖先組件中管理。這樣他們就都可以通過屬性接收到這份數據了。

當組件 B 需要對數據進行變更時,可以通過函數屬性來通知祖先組件對數據更新,然后重新傳遞給子組件。

唯一數據來源(Single source of truth)

有些同學可能又會迷惑,為什么多個組件之間必須要共用同一份數據,我可不可以引入一個事件庫,一個組件分發事件,另一個組件注冊相應的事件來接受數據自己維護。

類似的方案五花八門,會有很多,我認為這樣做當然是不好的,會有如下問題:

破壞了組件的封裝性,易于復用的組件都是相對獨立的,它只需要定義自己需要的數據和行為(函數屬性)即可,我不需要誰幫我分發事件。

數據傳遞是不連續的,這樣做會增加項目的復雜性,當項目到一定階段后,對這份數據的依賴就變得千絲萬縷、難以維護了。

相同的數據會有多個副本,需要保證數據同步,在增加項目復雜性的同時也提高了出現BUG的幾率。

這是我個人的看法,我也確實有遇到過這種用法,有不同意見大家可以進群交流。

數據唯一來源是官方推薦的數據共享的原則,也是最符合 React 設計理念,與單向數據流特性相輔相成的,希望大家務必遵守。

Redux

Redux 是一個狀態管理庫,它不是專屬于 React 技術棧的,但是跟 React 配合起來相當不錯。

當我們的前端應用規模較小的時候,我們可以不引入任何的狀態管理工具,只需要依據上面說的狀態提升的方式來管理應用狀態即可。為了讓應用的狀態更直觀,你可以將跟組件作為狀態總線,來管理整個應用所有的狀態。而且對于小規模的項目是推薦這樣來做的,沒有必要高射炮打蚊子,過渡設計。

但是當前端應用規模變得比較復雜時,我們就需要有類似 Redux 這樣一個來專門進行狀態管理的東西了。它的職責如下:

維護一個數據倉庫(store)管理整個應用的狀態(state),確保數據的唯一來源。

可以通過 dispatch 方法分發一個 action,來通知 Redux 需要對數據進行變更。

Redux 接收到 action 后可以依據 action 的類型對 state 進行相應的修改。

數據跟新后 Redux 會觸發注冊的監聽器(如:更新組件屬性),完成視圖更新。

Redux 跟 React 一起來用,更詳細的介紹可以參考:官方文檔,這里大家可以先簡單了解下,在后面關于 React 實戰的文章中也會詳細介紹 Redux 的使用。

類似的狀態管理工具還有:MobxJS,感興趣的同學也可以了解下。

關于組件通信的其他內容

在 React 中還有一些其他的與組件間通信相關的知識,這里也順便跟大家介紹下。

context

首先說一下,這是一個不推薦使用的特性,React 官方有明確說明,這是一個實驗性的API,可能會在后面的版本中去掉這個東西。所以我是從來不用的,呵呵!

context 的作用是啥呢,當大家有過 React 實戰經驗時,很容易遇到這種場景,如果組件的層級組織得不合適,可能會嵌套的非常深,當底層的一個組件需要使用頂層一個組件的數據時,需要通過屬性一層層傳遞下去,非常繁瑣。

context 就是解決這個問題的,只需要在頂層組件中聲明 context,那它的所有子組件可以通過 this.context 直接獲取得到。如下實例所示:

import React from "react";
import PropTypes from "prop-types";

class Button extends React.Component {
  render() {
    return (
      
    );
  }
}

Button.contextTypes = {
  color: PropTypes.string
};

class Message extends React.Component {
  render() {
    return (
      
{this.props.text}
); } } class MessageList extends React.Component { getChildContext() { return {color: "purple"}; } render() { const children = this.props.messages.map((message) => ); return
{children}
; } } MessageList.childContextTypes = { color: PropTypes.string };

實例中,組件層級關系是:MessageList -> Message -> Button。

MessageList 組件中維護一個 color 值用于 Button 組件的背景色,一般情況下我們需要將 color 以屬性的方式傳給 Message 組件,再通過屬性傳給 Button 組件。然后在實例中,通過 React 的 context 功能,MessageList 可以將 color 的值越過 Message 直接傳給 Button。

是不是很方便?確實很方便,但是這會導致數據傳遞不連續,過度使用會使得項目邏輯變得不直觀,增加項目維護的復雜性。

ref

每一個 React 組件有一個特殊的屬性 ref,該屬性的值可以是一個字符串,也可以是一個函數。由于字符串形式的 ref 在內部實現和實際使用中存在諸多問題,官方不推薦使用,而且可能在未來的版本中會移除,所以我們也沒必要聊它了,只要大家在看到字符串形式的 ref 屬性時知道也有這種用法就可以了。

ref 屬性值是一個函數時,如果組件是一個 HTML 元素兼容的 React 內部組件時(如:div、img 等),函數接收其對應的原生 DOM 節點作為參數。如果組件是一個我們以類的方式定義的組件時,函數接收該組件類的實例作為參數。需要注意的是,如果組件是一個以函數的方式定義的組件,那么設置為 ref 值得函數永遠都會接收到一個 null

那么 ref 與組件之間的通信有什么關系呢?請看上段文字加粗內容和下面這個實例:

class UserForm extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      name: null,
      age: null
    }
  }
  formData() {
    return this.state
  }
  handleFieldChange(e) {
    const { name, value } = e.target
    this.setState({
      [name]: value
    })
  }
  render() {
    return (
      
this.handleFieldChange(e)} /> this.handleFieldChange(e)} />
) } } class App extends React.Component { handleSubmit() { const formData = this.form.formData() alert(`formData: ${JSON.stringify(formData)}`) } render() { return (
{this.form = form}} />
) } } ReactDOM.render(, document.querySelector("#root"))

演示地址:https://codepen.io/Sarike/pen...

既然通過 ref 能夠獲取子組件的實例,那么我們自然可以調用其成員方法,從而獲取數據。

當然,目前這確實能工作,但絕對不是一種好的方式。因為作為一個組件,是需要有一定的封裝性的,它應該對外只會承諾我接受什么樣的屬性,而不會承諾有什么樣的成員方法。換句話說,如果 JavaScript 的類支持私有成員方法,那么 React 組件類中的成員方法都應該定義成私有的。

這應該屬于一種 Hack 的使用方式,而且這樣做有悖單向數據流原則。

ref 有它自己的使用場景,這里只是說明這種方式不適用于組件之間通信。

總結

雖然啰嗦了這么多,實際上只希望大家知道一件事情,請使用狀態提升的方式在多個組件之間共享數據,切記維持應用單向數據流和數據唯一來源原則。

文章中有些觀點仁者見仁,有什么疑惑歡迎留言討論。

好久沒更新了,但是沒有放棄,感謝大家支持。歡迎加我微信好友:leobaba88,進群交流。驗證信息:玩轉 React

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/90330.html

相關文章

  • 玩轉 React(一)- 前言

    摘要:本人計劃編寫一個針對中初級前端開發者學習的系列教程玩轉。使用的原因是新的語言規范開發效率更高代碼更優雅,尤其是基于開發的項目。其次也是目前特別流行的一個前端框架,截止目前,上有將近萬,國內一二線互聯網公司都有深度依賴開發的項目。 本人計劃編寫一個針對中初級前端開發者學習 React 的系列教程 - 《玩轉 React》。 文章更新頻率:每周 1 ~ 2 篇。 目錄 玩轉 React(...

    waltr 評論0 收藏0
  • react-control-center里玩轉無狀態組件

    摘要:類組件中的增加學習成本,類組件在基于現有工具的優化上存在些許問題。由于業務變動,函數組件不得不改為類組件等等。那么可愛的各位看官,還不趕緊使用起來在線示例點我版本基礎入門項目錄像教程 視圖與業務,好一對冤家 業務型model model是需要精心的設計和合理的劃分的,這是我們之前開發大型的redux+react單頁面應用,大家都認同的真理,同樣的,在react-control-cent...

    xiangzhihong 評論0 收藏0
  • 玩轉 React(二)- 新型前端開發方式

    摘要:這也就是所謂的單向數據流,在這種開發方式下,會讓你更新視圖的邏輯非常清晰簡單,哪怕你的前端交互很復雜,也不至于讓你的代碼那么容易變成一坨。就是在前端開發過程中,要善于觀察和抽象。 這是《玩轉 React》系列的第二篇。在該篇中,我們來了解下,React 的出現到底給我們的開發方式帶來了什么樣的變化。 我的感觸可以用一個字來形容,爽!主要爽在以下兩個方面。 視圖是數據的映射(單向數據流)...

    RdouTyping 評論0 收藏0
  • 玩轉 React(四)- 創造一個新 HTML 標簽

    摘要:屬性是一個組件的外部輸入。只會在開發模式下進行屬性類型檢查,當代碼進行生產發布后,為了減少額外的性能開銷,類型檢查將會被略過。某個類的實例枚舉,屬性值必須為其中的某一個值。屬性為一個數組,且數組中的元素必須符合指定類型。 在第二篇文章 《新型前端開發方式》 中有說到 React 有很爽的一點就是給我們一種創造 HTML 標簽的能力,那么今天這篇文章就詳細講解下 React 是如何提供這...

    soasme 評論0 收藏0
  • 玩轉 React(四)- 創造一個新 HTML 標簽

    摘要:屬性是一個組件的外部輸入。只會在開發模式下進行屬性類型檢查,當代碼進行生產發布后,為了減少額外的性能開銷,類型檢查將會被略過。某個類的實例枚舉,屬性值必須為其中的某一個值。屬性為一個數組,且數組中的元素必須符合指定類型。 在第二篇文章 《新型前端開發方式》 中有說到 React 有很爽的一點就是給我們一種創造 HTML 標簽的能力,那么今天這篇文章就詳細講解下 React 是如何提供這...

    dendoink 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<