React 源码系列 | React Context 详解

目前来看 Context 是一个非常强大但是很多时候不会直接使用的 api。大多数项目不会直接使用 createContext 然后向下面传递数据,而是采用第三方库(react-redux)。

想想项目中是不是经常会用到 @connect(...)(Comp) 以及 <Provider value={store}><App /></Provider>

什么是 Context

Context 提供了一个无需为每层组件手动添加 props,就能在组件树间进行数据传递的方法。

一个顶层数据,想要传递到某些深层组件,通过 props 逐层传递将会非常繁琐,使用 Context 可避免显式地通过组件树逐层传递 props

Context 使用示例

import React, { Component, createContext, useConText } from 'react'
const ColorContext = createContext(null)
const { Provider, Consumer } = ColorContext

console.log('ColorContext', ColorContext)
console.log('Provider', Provider)
console.log('Consumer', Consumer)

class App extends Component {
  constructor(props) {
    super(props)
    this.state = {
      color: 'red',
      background: 'cyan',
    }
  }
  render() {
    return <Provider value={this.state}>{this.props.children}</Provider>
  }
}
function Article({ children }) {
  return (
    <App>
      <h1>Context</h1>
      <p>hello world</p>
      {children}
    </App>
  )
}
function Paragraph({ color, background }) {
  return (
    <div style={
    { backgroundColor: background }}>
      <span style={
    { color }}>text</span>
    </div>
  )
}
function TestContext() {
  return (
    <Article>
      <Consumer>{state => <Paragraph {...state} />}</Consumer>
    </Article>
  )
}

export default TestContext

页面呈现出的效果

640?wx_fmt=png

打印 ColorContextProviderConsumer

640?wx_fmt=png

createContext

// createContext 可以让我们实现状态管理
// 还能够解决传递 Props drilling 的问题
// 假如一个子组件需要父组件的一个属性,但是中间间隔了好几层,这就会出现开发和维护的一个成本。这时候就可以通过这个 API 来解决
function createContext(defaultValue, calculateChangedBits) {
  var context = {
    $$typeof: REACT_CONTEXT_TYPE,
    _calculateChangedBits: calculateChangedBits,
    // As a workaround to support multiple concurrent renderers, we categorize
    // some renderers as primary and others as secondary. We only expect
    // there to be two concurrent renderers at most: React Native (primary) and
    // Fabric (secondary); React DOM (primary) and React ART (secondary).
    // Secondary renderers store their context values on separate fields.
    // 以下两个属性是为了适配多平台
    _currentValue: defaultValue,
    _currentValue2: defaultValue,
    // Used to track how many concurrent renderers this context currently
  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值