摘要:丟失問題文本是為了說清目前的機制是而不是我們以為的機制,并說明這兩者的區別。雖然明白了原理,但是問題并沒有解決。上下文注意這里是,需要執行接受回調函數,回調函數中的內容為實測可以成功拿到。
React context 丟失問題
什么是 context文本是為了說清react context目前的機制是owner context 而不是我們以為的parent context 機制,并說明這兩者的區別。希望能對即將使用context的同學有所幫助.
context是為了解決component之間通信的上下文機制,該api目前并未定稿所以react并沒有開放出來。最近有大量需要共享上下文的場景才去了解這個api,然后也成功被繞了進去....
介紹與用法這篇文章Introduction to Contexts in React.js說得很清楚~
需要在Parent中聲明context,在Children中拿到context并打印出來。
var Children = React.createClass({ contextTypes: { value: React.PropTypes.string }, render: function() { return{this.context.value || "并沒有context"}; } }); var Parent = React.createClass({ childContextTypes: { value: React.PropTypes.string }, getChildContext: function() { return { value: "上下文" }; }, render: function() { return ({this.props.children}); } }); var App = React.createClass({ render: function() { return (); } }); React.render(React.createElement(App), document.body);
這樣執行完后屏幕上應該是『上下文』三個打字,但事實是
以及warning
那么問題來了,上下文為何失效了呢?!為什么Children拿不到Parent里面的context呢?!
find the problem各種google之后發現gaearon大神在issue中的回復。
原來現在0.13.3版本的react context的傳遞規則是owner規則,在剛才的例子中雖然Children的parent為Parent,但是App才是Children與parent共同的owner,this.context只能拿到owner傳遞規則的context。
尼瑪,跟想象中的不一樣啊!你props、render的規則不都是Parent規則么!
不繼續吐槽,那么按照這個思路把context放在App上,Parent與Children應該都能成功拿到Context了吧。
代碼是這樣的:
var Parent = React.createClass({ contextTypes: { value: React.PropTypes.string }, render: function() { return ({this.context.value && "可算拿到了..." } {this.props.children}); } }); var App = React.createClass({ childContextTypes: { value: React.PropTypes.string }, getChildContext: function() { return { value: "上下文" }; }, render: function() { return (); } }); React.render(React.createElement(App), document.body);
結果是這樣的:
看來context成功被拿到,看到這里大家應該明白React context的機制了把。
how to get parent context雖然明白了原理,但是問題并沒有解決。我就是希望Chilren拿到Parent中的context,而不是拿到App中的context啊。我目前一共找到了兩種方式可以在現階段獲取parent context。
1. use the callback通過接收回調函數而不是react.element,然后在Parent中進行render,那么render的內容的owner自然就是Parent了,從而可以成功拿到Parent中的context。
var Parent = React.createClass({ childContextTypes: { value: React.PropTypes.string }, getChildContext: function() { return { value: "上下文" }; }, render: function() { return ({this.props.children() /* 注意這里是function,需要執行 */}); } }); // parent接受回調函數,回調函數中的內容owner為parent var App = React.createClass({ render: function() { return ({this.renderChild} ); }, renderChild: function() { return; } });
實測可以成功拿到context。
2.通過this._reactInternalInstance這種方法雖然用起來很方便不過健壯性很差,等react更新之后沒準又得改代碼~
可以通過this._reactInternalInstance._context.value拿到該element的parent context。this._reactInternalInstance._currentElement._context.value就是默認的owner context。
var Children = React.createClass({ contextTypes: { value: React.PropTypes.string }, render: function() { return
結果如下:
context es6 寫法由于同事問我es6下context怎么用,想到可能有些人也不清楚,在這里一并附上。個人不推薦使用es7語法。
import React from "react"; class Children extends React.Component { // 如果不需要在構造函數中使用可以不寫,沒有影響 constructor(props, context) { super(props, context); console.log(context); } render() { return
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/85846.html
摘要:等等這不就用的將的給覆蓋了么這也很合理的解釋了為啥會報錯了。嗯還是拿不到,想起來了,雖然將靜態屬性拿了出來,但是原型方法不會拿出來啊,所以的就沒用了,所以我們需要也將他拿出來,于是,加上一下代碼這次總算拿到正確的結果了,開心 踩坑場景 在做業務的時候,有些模塊是可以拖動的,恰好這些模塊需要從根組件App的context上拿屬性,同時App也是作為拖動上下文,被@DragDropCont...
摘要:指定讀取當前的。它為其后代元素觸發額外的檢查和警告。嚴格模式檢查僅在開發模式下運行它們不會影響生產構建。作用識別不安全的生命周期關于使用過時字符串的警告關于使用廢棄的方法的警告檢測意外的副作用檢測過時的為高階組件。 react 進階 懶加載 React.lazy函數能讓你像渲染常規組件一樣處理動態引入(的組件)。Suspense加載指示器為組件做優雅降級。fallback屬性接受任何在...
摘要:電影天堂客戶端重新開始具體更新以為準。重新開始兩年前發布了第一個版本。最為一名偏體驗偏設計的前端開發者,對界面和用戶體驗都有極高的重視。 電影天堂React Native 客戶端 重新開始! 具體更新以https://github.com/XboxYan/DYTT為準。 重新開始 兩年前發布了第一個版本。 現在, 使用最新的react-native 0.57和全新的設計完成了V2.0 ...
摘要:在幾天前發布了新版本,被合入。但是在版本迭代的背后很多有趣的設計值得了解。參數處理這項改動由提出。對透明化處理中的,達到將包裹起來的目的。對的凍結認為,在中使用和方法是一種反模式。尤其是這樣的新,某些開發者認為將逐漸取代。 showImg(https://segmentfault.com/img/remote/1460000014571148); Redux 在幾天前(2018.04....
閱讀 1810·2021-08-13 15:06
閱讀 3100·2021-08-05 10:02
閱讀 3365·2019-08-30 15:55
閱讀 2378·2019-08-30 13:46
閱讀 2485·2019-08-30 13:01
閱讀 1323·2019-08-29 17:17
閱讀 2824·2019-08-29 15:27
閱讀 1431·2019-08-29 11:12