Context 通过组件树提供了一个传递数据的方法, 从而避免了在每一个层级手动的传递 props 属性.
在一个典型的 React 应用中, 数据是通过 props 属性由上向下 (由父及子) 的进行传递的, 但这对于某些类型的属性而言是极其繁琐的(例如: 地区偏好, UI 主题), 这是应用程序中许多组件都所需要的. Context 提供了一种在组件之间共享此类值的方式, 而不必通过组件树的每个层级显式地传递 props .
老版本的 context API
- import React, { Component } from 'react';
- import './App.CSS';
- import PropTypes from 'prop-types';
- const Topic = (props) => {
- return (
- <div>
- <Comment />
- </div>
- )
- }
- const Comment = (props, context) => {
- return (
- <div>{ context.color }</div>
- )
- }
- Comment.contextTypes = {
- color: PropTypes.string
- }
- class App extends Component {
- getChildContext() {
- return { color: "red" };
- }
- render() {
- return (
- <div className="App">
- <Topic />
- </div>
- );
- }
- }
- App.childContextTypes = {
- color: PropTypes.string
- }
- export default App;
新版本 16.3 context
- import React, { Component } from 'react';
- import './App.css';
- // 第一步, 创建 context
- const myContext = React.createContext()
- // 第二步, 创建 Provider Component
- class MyProvider extends Component {
- state = {
- name: "rails365",
- age: 27
- }
- render() {
- return (
- <myContext.Provider value={{ state: this.state }}>
- { this.props.children }
- </myContext.Provider>
- )
- }
- }
- const Family = (props) => {
- return (
- <div>
- <h1>Family</h1>
- <Person />
- </div>
- )
- }
- class Person extends Component {
- render() {
- return (
- <div>
- <h1>Person</h1>
- <myContext.Consumer>
- { ({ state }) => <p>My age is { state.age }</p> }
- </myContext.Consumer>
- </div>
- );
- }
- }
- class App extends Component {
- render() {
- return (
- <div className="App">
- <p>Hello App</p>
- <MyProvider>
- <Family />
- </MyProvider>
- </div>
- );
- }
- }
- export default App;
- API
- React.createContext
- const {
- Provider, Consumer
- } = React.createContext(defaultValue);
创建一对 { Provider, Consumer }. 当 React 渲染 context 组件 Consumer 时, 它将从组件树的上层中最接近的匹配的 Provider 读取当前的 context 值.
如果上层的组件树没有一个匹配的 Provider, 而此时你需要渲染一个 Consumer 组件, 那么你可以用到 defaultValue . 这有助于在不封装它们的情况下对组件进行测试.
- Provider
- <Provider value={
- /* some value */
- }>
React 组件允许 Consumers 订阅 context 的改变.
接收一个 value 属性传递给 Provider 的后代 Consumers. 一个 Provider 可以联系到多个 Consumers.Providers 可以被嵌套以覆盖组件树内更深层次的值.
- Consumer
- <Consumer>
- {value => /* render something based on the context value */}
- </Consumer>
一个可以订阅 context 变化的 React 组件.
接收一个 函数作为子节点. 函数接收当前 context 的值并返回一个 React 节点. 传递给函数的 value 将等于组件树中上层 context 的最近的 Provider 的 value 属性. 如果 context 没有 Provider , 那么 value 参数将等于被传递给 createContext() 的 defaultValue .
来源: https://juejin.im/post/5c0c7f1d518825750046c0b7