Contexts 是React的一個重要屬性,可是到目前爲止,這個屬性在正式的文檔裏面尚未對它進行正式介紹,在 reactv0.1.4將會正式發佈這個屬性。下面先來介紹一下它的使用方式。javascript
React.withContext
會執行一個指定的上下文信息的回調函數,任何在這個回調函數裏面渲染的組件都有這個context的訪問權限。java
var A = React.createClass({ contextTypes: { name: React.PropTypes.string.isRequired, }, render: function() { return <div>My name is: {this.context.name}</div>; } }); React.withContext({'name': 'Jonas'}, function () { // Outputs: "My name is: Jonas" React.render(<A />, document.body); });
任何想訪問context裏面的屬性的組件都必須顯式的指定一個contextTypes
的屬性。若是沒有指定改屬性,那麼組件經過 this.context 訪問屬性將會出錯。react
若是你爲一個組件指定了context,那麼這個組件的子組件只要定義了contextTypes 屬性,就能夠訪問到父組件指定的context了。函數
var A = React.createClass({ render: function() { return <B />; } }); var B = React.createClass({ contextTypes: { name: React.PropTypes.string }, render: function() { return <div>My name is: {this.context.name}</div>; } }); React.withContext({'name': 'Jonas'}, function () { React.render(<A />, document.body); });
爲了減小文件的引用,你能夠爲contextTypes
放到一個minx 中,這樣 用到的組件引用這個 minx
就好了。ui
var ContextMixin = { contextTypes: { name: React.PropTypes.string.isRequired }, getName: function() { return this.context.name; } }; var A = React.createClass({ mixins: [ContextMixin], render: function() { return <div>My name is {this.getName()}</div>; } }); React.withContext({'name': 'Jonas'}, function () { // Outputs: "My name is: Jonas" React.render(<A />, document.body); });
和訪問context 的屬性是須要經過 contextTypes
指定可訪問的 元素同樣。getChildContext
指定的傳遞給子組件的屬性須要先經過 childContextTypes
來指定,否則會產生錯誤。this
// This code *does NOT work* becasue of a missing property from childContextTypes var A = React.createClass({ childContextTypes: { // fruit is not specified, and so it will not be sent to the children of A name: React.PropTypes.string.isRequired }, getChildContext: function() { return { name: "Jonas", fruit: "Banana" }; }, render: function() { return <B />; } }); var B = React.createClass({ contextTypes: { fruit: React.PropTypes.string.isRequired }, render: function() { return <div>My favorite fruit is: {this.context.fruit}</div>; } }); // Errors: Invariant Violation: A.getChildContext(): key "fruit" is not defined in childContextTypes. React.render(<A />, document.body);
假設你的應用程序有多層的context。經過withContext
和 getChildContext
指定的context元素均可以被子組件引用。可是子組件是須要經過 contextTypes
來指定所須要的context 元素的。code
var A = React.createClass({ childContextTypes: { fruit: React.PropTypes.string.isRequired }, getChildContext: function() { return { fruit: "Banana" }; }, render: function() { return <B />; } }); var B = React.createClass({ contextTypes: { name: React.PropTypes.string.isRequired, fruit: React.PropTypes.string.isRequired }, render: function() { return <div>My name is: {this.context.name} and my favorite fruit is: {this.context.fruit}</div>; } }); React.withContext({'name': 'Jonas'}, function () { // Outputs: "My name is: Jonas and my favorite fruit is: Banana" React.render(<A />, document.body); });
context 是就近引用的,若是你經過withContext
指定了context元素,而後又經過 getChildContext
指定了該元素,該元素的值將會被覆蓋。ip
var A = React.createClass({ childContextTypes: { name: React.PropTypes.string.isRequired }, getChildContext: function() { return { name: "Sally" }; }, render: function() { return <B />; } }); var B = React.createClass({ contextTypes: { name: React.PropTypes.string.isRequired }, render: function() { return <div>My name is: {this.context.name}</div>; } }); React.withContext({'name': 'Jonas'}, function () { // Outputs: "My name is: Sally" React.render(<A />, document.body); });
經過context傳遞屬性的方式能夠大量減小 經過顯式的經過 props
逐層傳遞屬性的方式。這樣能夠減小組件之間的直接依賴關係。ci