乐趣区

关于javascript:聊聊React的Context

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 - 定义 contextType
import {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

// 待续补坑
退出移动版