React-組件間通信

父子間組件通信

父結點數據傳遞給子組件 通過 props進行傳遞,子組件只能用于展示或者判斷盔然,但不能進行更新
當子組件需要通知父組件數據變化時,父組件通過把函數作為一個props傳遞持偏,子組件只需要按需調用就可以了

非父子組件間通信

ContextAPI 在頂層進行數據定義蹂喻,在這個組件樹的所有組件就能通過 Context 的API進行獲取和修改
Context 提供了一個無需為每層組件手動添加 props筏餐,就能在組件樹間進行數據傳遞的方法开泽。

React.createContext

創(chuàng)建一個 Context 對象。
const MyContext = React.createContext(defaultValue);
defaultValue
不止是一個值魁瞪,也可以是一個對象{value穆律,changeValue()} 也可以提供這樣的方法進行修改value

當 React 渲染一個訂閱了這個 Context 對象的組件,這個組件會從組件樹中離自身最近的那個匹配的 Provider 中讀取到當前的 context 值导俘。

只有當組件所處的樹中沒有匹配到 Provider 時峦耘,其 defaultValue 參數才會生效。
這有助于在不使用 Provider 包裝組件的情況下對組件進行測試旅薄。
注意:將 undefined 傳遞給 Provider 的 value 時辅髓,消費組件的 defaultValue 不會生效。

Context.Provider
 <MyContext.Provider value={/* 某個值 */}>
  <消費組件 />
 </MyContext.Provider>

每個 Context 對象都會返回一個 Provider React 組件少梁,它允許消費組件訂閱 context 的變化洛口。

Provider 接收一個 value 屬性,傳遞給消費組件凯沪。一個 Provider 可以和多個消費組件有對應關系第焰。
多個 Provider 也可以嵌套使用,里層的會覆蓋外層的數據妨马。

當 Provider 的 value 值發(fā)生變化時挺举,它內部的所有消費組件都會重新渲染。
Provider 及其內部 consumer 組件都不受制于 shouldComponentUpdate 函數烘跺,因此當 consumer 組件在其祖先組件退出更新的情況下也能更新湘纵。

當Provider所在的父組件進行重新渲染時,會導致下邊所有消費組件全部重新渲染滤淳,即使Provider的value沒有發(fā)生改變瞻佛。為了避免這種事情的發(fā)生,
可以考慮把Provider的value先綁定在父組件的state上。這樣當父組件進行重新渲染時就不會發(fā)生因為value是一個新對象而引發(fā)消費組件的渲染伤柄。
這個是官方的解釋绊困,但實質上并不是這樣。
Context.Provider說到底還是組件适刀,也按照組件基本法來辦事秤朗,當value發(fā)生變化時,它也可以不引發(fā)子組件的渲染笔喉。
前提是取视,子組件作為一個屬性(this.props.children)也要保持不變才行。
如果子組件變了常挚,Context.Provider 也不知道你是不是以前的你作谭,只好讓你重畫了。
看官網中的注意事項的時候能夠發(fā)現給出的代碼中Provider變成了一個單獨的組件奄毡,對于獨立的Provider組件內部構成并沒有說明折欠。

具體解釋:https://zhuanlan.zhihu.com/p/50336226

const MyContext = React.createContext('light');

class Provider extende React.Component{
  constructor(){
    this.state = {
      value:'dark'
    }
  }
  render (){
    return (
      <MyContext.Provider value={this.state.value}>
        {this.props.children}
      </MyContext.Provider>
    )
  }
}

class MyContextRoot extende React.Component{
  render (){
    return (
      <Provider>
        <Child />
      </Provider>
    )
  }
}

Class.contextType

掛載在 class 上的 contextType 屬性會被重賦值為一個由 React.createContext() 創(chuàng)建的 Context 對象。
注意這種方法只能掛載一個context吼过,如果需要多個锐秦,只能使用Context.Consumer進行多層嵌套

方法一:

這能讓你使用 this.context 來消費最近 Context 上的那個值。
你可以在任何生命周期中訪問到它盗忱,包括 render 函數中酱床。

class MyClassContext extende Component {
  var value = this.context;
}
MyClassContext.contextType = MyContext
方法二:

可以通過static方法綁定(class Fields)

class MyClassContext extende Component{
  static mycontext = MyContext;
}

Context.Consumer

一個 React 函數式組件 可以訂閱 context 的變更,這讓你在函數式組件中可以訂閱 context趟佃。
同時 類組件也通過這種方式訂閱多個Context

function MyFuncContext(){
  return (
    <MyContext.Consumer>
      {(value)=>({
        <span>{value}</span>
      })}
    </MyContext.Consumer>
  )
}

這種方法需要一個函數作為子元素(function as a child)扇谣。
這個函數接收當前的 context 值,并返回一個 React 節(jié)點闲昭。
傳遞給函數的 value 值等價于組件樹上方離這個 context 最近的 Provider 提供的 value 值揍堕。
如果沒有對應的 Provider,value 參數等同于傳遞給 createContext() 的 defaultValue汤纸。

Context.displayName

context 對象接受一個名為 displayName 的 property衩茸,類型為字符串。React DevTools 使用該字符串來確定 context 要顯示的內容贮泞。

const MyContext = React.createContext(/* some value */);
MyContext.displayName = 'MyDisplayName';

代碼地址

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
禁止轉載楞慈,如需轉載請通過簡信或評論聯(lián)系作者。
  • 序言:七十年代末啃擦,一起剝皮案震驚了整個濱河市囊蓝,隨后出現的幾起案子,更是在濱河造成了極大的恐慌令蛉,老刑警劉巖聚霜,帶你破解...
    沈念sama閱讀 222,000評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件狡恬,死亡現場離奇詭異,居然都是意外死亡蝎宇,警方通過查閱死者的電腦和手機弟劲,發(fā)現死者居然都...
    沈念sama閱讀 94,745評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來姥芥,“玉大人兔乞,你說我怎么就攤上這事×固疲” “怎么了庸追?”我有些...
    開封第一講書人閱讀 168,561評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長台囱。 經常有香客問我淡溯,道長,這世上最難降的妖魔是什么簿训? 我笑而不...
    開封第一講書人閱讀 59,782評論 1 298
  • 正文 為了忘掉前任咱娶,我火速辦了婚禮,結果婚禮上煎楣,老公的妹妹穿的比我還像新娘。我一直安慰自己车伞,他們只是感情好择懂,可當我...
    茶點故事閱讀 68,798評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著另玖,像睡著了一般困曙。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上谦去,一...
    開封第一講書人閱讀 52,394評論 1 310
  • 那天慷丽,我揣著相機與錄音,去河邊找鬼鳄哭。 笑死要糊,一個胖子當著我的面吹牛,可吹牛的內容都是我干的妆丘。 我是一名探鬼主播锄俄,決...
    沈念sama閱讀 40,952評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼勺拣!你這毒婦竟也來了奶赠?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,852評論 0 276
  • 序言:老撾萬榮一對情侶失蹤药有,失蹤者是張志新(化名)和其女友劉穎毅戈,沒想到半個月后,有當地人在樹林里發(fā)現了一具尸體,經...
    沈念sama閱讀 46,409評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡苇经,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,483評論 3 341
  • 正文 我和宋清朗相戀三年赘理,在試婚紗的時候發(fā)現自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片塑陵。...
    茶點故事閱讀 40,615評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡感憾,死狀恐怖,靈堂內的尸體忽然破棺而出令花,到底是詐尸還是另有隱情阻桅,我是刑警寧澤,帶...
    沈念sama閱讀 36,303評論 5 350
  • 正文 年R本政府宣布兼都,位于F島的核電站嫂沉,受9級特大地震影響,放射性物質發(fā)生泄漏扮碧。R本人自食惡果不足惜趟章,卻給世界環(huán)境...
    茶點故事閱讀 41,979評論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望慎王。 院中可真熱鬧蚓土,春花似錦、人聲如沸赖淤。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,470評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽咱旱。三九已至确丢,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間吐限,已是汗流浹背鲜侥。 一陣腳步聲響...
    開封第一講書人閱讀 33,571評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留诸典,地道東北人描函。 一個月前我還...
    沈念sama閱讀 49,041評論 3 377
  • 正文 我出身青樓,卻偏偏與公主長得像狐粱,于是被迫代替她去往敵國和親赘阀。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,630評論 2 359

推薦閱讀更多精彩內容