React-StepPitGuide
  • 封面
  • 前言
  • 基础知识
    • 环境配置
      • WebPack 前端打包工具
      • Babel 编译器
      • Node 环境配置
    • 版本说明
    • JSX
    • 组件
    • Child组件
    • 多组件嵌套
    • 组件生命周期
      • 组件生命周期(React16之前)
    • State属性
    • Props属性
    • 类组件
      • React PropTypes
      • React 可复用组件
      • React 事件与数据的双向绑定
      • React 组件DOM操作
      • React 独立组件间共享 Mixins ⚠
      • React 高阶组件(HOC)
        • 继承方式的高阶组件
        • 代理方式的高阶组件
      • React 无状态组件与PureComponent
      • React 容器组件和展示组件
      • setState
    • 函数组件
      • React 函数子组件
      • React Hook
        • useState
        • useEffect
    • 组件样式
      • CSS內联式样
      • CSS模块化
    • 受控与非受控组件
  • 进阶知识
  • React Context
  • React 顶级API
  • React Portal 传送门
  • 应用知识
    • 路由
      • React-Router2
      • React-router4
        • React-router4 结合React-Redux
    • 服务端渲染
    • 性能优化
      • React 组件优化
        • 定制shouldComponentUpdate
        • PureComponent
        • immutablejs存在的意义和使用
      • Redux性能优化
      • React同构
    • 项目应用
      • React 文件组织方式
      • React 模块接口
      • React 合并reducer
      • React 问题
  • 状态管理
    • Flux
    • Redux
      • Redux 使用
      • Redux 异步
      • Redux Chrome插件使用
      • Redux React-Redux
      • Redux applyMiddleware
      • Redux 结合React
      • Redux 自制Redux
      • Redux 自制React-Redux
      • Redux 自制thunk中间件
      • Redux 自制arr中间件
    • Mobx
      • Mobx 思想
    • RXJS
    • immutable
  • 源码思考
    • 简述
    • SimpleReact
    • 虚拟DOM
      • 虚拟DOM概念(React 16前)
      • 虚拟DOM思考(React 16前)
    • 生命周期
    • 事件
    • Fiber
      • 数据结构
      • Scheduler 调度
      • Concurrent 异步渲染
    • Hooks
      • useState
由 GitBook 提供支持
在本页

这有帮助吗?

React Context

当在多层组件中,如果传递层数过多,如以下实例:

import React from 'react'

//3
class Navbar extends React.Component{
  render(){
    return(
      <div>{this.props.user}的导航栏</div>
    )
  }
}

//2
class Sidebar extends React.Component{
  render(){
     return(
      <div>
        <p>侧边栏</p>
        <Navbar user={this.props.user}></Navbar>
      </div>
     )
  }
}

//1
class Page extends React.Component{
  render(){
    const user = 'TYRMars'
    return(
      <div>
        <p>我是{user}</p>
        <Sidebar user={this.props.user}/>
      </div>
    )
  }
}

就会出现中间组件只是作为参数传递。

如果层数再次增加,而且最外层传入一个参数,只有最内层使用,这就需要中间每一层帮忙传递。

所以在使用Redux的时候,通过props传递state不是一个很好的方法。

不过呢,React提供了一个很不错的功能,能很好的解决这个问题。那就是Context

Context

Context是全局的,就是“上下文环境”,所有子元素都可以直接获取。

  1. 顶层组件进行Context的设置,提供一个函数来返回代表Context的对象

  2. 对顶层组件之下的组件,声称其需要这个Context,可以通过this.context访问到这个共同的环境变量

我们可以自定义一个Provider的React组件

import {PropType,Component} from 'react'
//React16之后PropType与React分开,单独了出来,详细请查看React PropsTypes
class Provider extends React.Component{
  getChildContext(){
    return {
     store:this.props.store
    };
  }
  render(){
    return this.props.children;
  }
}

Provider.childContextType = {
  store:PropTypes.object
}

export default Provider

改进相关的index.js入口文件

import {Store} from './Store.js' 
import ReactDOM from 'react'
import Provider from './Provider.js'

ReactDOM.render(
 <Provider>
   <Page/>
 </Provider>
 ,document.getElementById('root')
);

给ControlPanel包一层Provider,Provider提供了Context,也就是通过这种方式,让Context覆盖所有组件

import React from 'react'

Navbar.contextTypes = {
 store:PropType.object
}

//3
class Navbar extends React.Component{
  render(){
    return(
      <div>{this.context.store.user}的导航栏</div>
    )
  }
}

在最底层直接引入Context,相应的store就能通过this.context.store读取出来

如果定义了构造函数就要把context以参数形式引入

constructor(props,context){
  super(props,context)
}

对实例进行修改

import React from 'react'
import PropTypes from 'prop-types'

//3
class Navbar extends React.Component{
  static contextTypes = {
    user:PropTypes.String
  }
  render(){
    console.log(this.context)
    return(
      <div>{this.props.user}的导航栏</div>
    )
  }
}

//2
class Sidebar extends React.Component{
  render(){
     return(
      <div>
        <p>侧边栏</p>
        <Navbar></Navbar>
      </div>
     )
  }
}

//1
class Page extends React.Component{
  //React16的proptypes校验方法
  static childContextTypes = {
    user:PropTypes.String
  }
  constructor(props){
    super(props)
    this.state = {user:'TYRMars'}
  }
  getChildContext(){
    return this.state
  }
  render(){
    return(
      <div>
        <p>我是{this.state.user}</p>
        <Sidebar/>
      </div>
    )
  }
}
上一页受控与非受控组件下一页React 顶级API

最后更新于4年前

这有帮助吗?