1、context的理解react
不少優秀的React組件都經過Context來完成本身的功能,好比react-redux的<Provider />,就是經過Context提供一個全局態的store,拖拽組件react-dnd,經過Context在組件中分發DOM的Drag和Drop事件,路由組件react-router經過Context管理路由狀態等等。在React組件開發中,若是用好Context,可讓你的組件變得強大,並且靈活redux
當你不想在組件樹中經過逐層傳遞props或者state的方式來傳遞數據時,可使用Context來實現跨層級的組件數據傳遞react-router
使用context能夠實現跨組件傳遞app
2、如何使用contextide
若是要Context發揮做用,須要用到兩種組件,一個是Context生產者(Provider),一般是一個父節點,另外是一個Context的消費者(Consumer),一般是一個或者多個子節點。因此Context的使用基於生產者消費者模式。函數
對於父組件,也就是Context生產者,須要經過一個靜態屬性childContextTypes聲明提供給子組件的Context對象的屬性,並實現一個實例getChildContext方法,返回一個表明Context的對象this
一、getChildContext 根組件中聲明,一個函數,返回一個對象,就是contextspa
二、childContextTypes 根組件中聲明,指定context的結構類型,如不指定,會產生錯誤code
三、contextTypes 子孫組件中聲明,指定要接收的context的結構類型,能夠只是context的一部分結構。contextTypes 沒有定義,context將是一個空對象。component
四、this.context 在子孫組件中經過此來獲取上下文
3、代碼演示
目錄結構
src/app.js
src/index.js
src/components/one.js
src/components/two.js
src/components/three.js
一、app.js
import React, { Component } from 'react'; import One from "./components/one"; import PropTypes from "prop-types"; class App extends Component { //根組件中聲明,指定context的結構類型,如不指定,會產生錯誤 static childContextTypes = { name:PropTypes.string, age:PropTypes.number, } //根組件中聲明,一個函數,返回一個對象,就是context getChildContext(){ return { name:"zhangsan", age:18, } }; render() { return ( <div> <One/> </div> ); } } export default App;
二、one.js
import React, { Component } from 'react' import Two from "./two"; import PropTypes from "prop-types"; export default class One extends Component { /* contextTypes 子孫組件中聲明,指定要接收的context的結構類型, contextTypes 沒有定義,context將是一個空對象。 */ static contextTypes = { name:PropTypes.string, age:PropTypes.number } render() { console.log(this) return ( <div> <Two/> </div> ) } }
三、two.js
import React, { Component } from 'react' import Three from "./three"; import PropTypes from "prop-types"; export default class Two extends Component { static contextTypes = { name:PropTypes.string, age:PropTypes.number } render() { console.log(this) return ( <div> <Three/> </div> ) } }
四、three.js
import React, { Component } from 'react' import PropTypes from "prop-types"; export default class Three extends Component { static contextTypes = { name:PropTypes.string, age:PropTypes.number } render() { console.log(this) return ( <div> </div> ) } }
五、結果
4、總結
一、context在以下的生命週期鉤子中可使用
constructor(props, context)
componentWillReceiveProps(nextProps, nextContext)
shouldComponentUpdate(nextProps, nextState, nextContext)
componentWillUpdate(nextProps, nextState, nextContext)
componentDidUpdate(prevProps, prevState, prevContext)
二、context的侷限性
1. 在組件樹中,若是中間某一個組件 ShouldComponentUpdate return false 了,會阻 礙 context 的正常傳值,致使子組件沒法獲取更新。
2. 組件自己 extends React.PureComponent 也會阻礙 context 的更新。