Context概念

个别用在跨组件通信中。

如下面的组件树中,A组件与B组件之间隔着十分多的组件,如果A组件心愿传递给B组件一个属性,那么不得不应用props将属性从A组件历经一系列两头组件传递给B组件。
这样代码不仅十分的麻烦,更重要的是两头的组件可能压根就用不上这个属性,却要承当一个传递的职责,这是咱们不心愿看见的。
Context呈现的目标就是为了解决这种场景,使得咱们能够间接将属性从A组件传递给B组件。

旧Context(不举荐应用)

过期的API官网文档传送门

根本用法

假设,ABC三个组件,AC为祖孙关系,AB父子关系,当初应用context由A向C传递属性text

class A extends React.Component {    getChildContext() {        return { text: 'Hello孙子' }    }    render() {        return (            <div>组件A蕴含<B/></div>        )    }}A.childContextTypes = { text: PropTypes.string };class B extends React.Component {    render() {        return (            <div>组件B蕴含<C/></div>        )    }}class C extends React.Component {    render() {        const { text } = this.context;        return (            <div>我是C我接管到A传递的内容是{text}</div>        )    } }C.contextTypes = { text: PropTypes.string }

注意上述代码中用以提供contextAPI,只有给下层组件增加getChildContextchildContextTypesReact将主动向下传递信息,子树上的所有组件能够通过定义 contextTypes 来拜访 context

带来的问题

如果咱们想要更新context,那么只能通过更新state或者props并将其值赋值给context

class A extends React.Component {    constructor(props) {        super(props);        this.state = { text: 'Hello孙子' };    }    getChildContext() {        return { text: this.state }    }    updateState = () => {        this.state = { text: '我是你爷爷' };    }    render() {        return (            <div onClick={this.updateState} >组件A蕴含<B /></div>        )    }}A.childContextTypes = { text: PropTypes.string };

然而,如果A组件提供的一个context产生了变动,而两头父组件(B)的 shouldComponentUpdate 返回 false,那么实际上B和C都不会进行更新。应用了context的组件则齐全失控,所以基本上没有方法可能牢靠的更新context

新Context

官网文档传送门

还是上述例子,AC祖孙组件通信。应用createContext能够构建一个Provider用以给孙子组件传递props

const defaultVal = { text: 'Hello,孙子' };const AContext = React.createContext(defaultVal);class App extends React.Component {    constructor(props) {         ...,        this.state = { text: '这里是新的内容' }    }    render() {        return (            <AContext.Provider value={this.state}>                <B />            </AContext.Provider>        )    }}// 接管形式1-定义contextTypeimport { AContext } from './A';class C extends React.Component {    static contextType = AContext;        render() {        const { text } = this.context;        return (            <div>我是C我接管到A传递的内容是{text}</div>        )    } }// 接管形式2-应用consumer// consumer次要用以函数组件渲染import { AContext } from './A';class C extends React.Component {    render() {        return (            <AContext.Consumer>                ({ text }) => (                    <p>我是C我接管到A传递的内容是{text}</p>                )            </AContext.Consumer>        )    } }

Redux中的Context

// 待续补坑