react的context

本文深入讲解React的Context API,探讨其在多层组件间数据传递的优势。通过实例演示如何创建和使用Context,对比旧版API,揭示新版API的穿透能力,使数据流动更加高效。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

当我们需要使用到一个数据,需要传递多层的时候,props往往显得心累,而我们又不需要引入redux的时候,可以使用react的context

首先使用createContext创建一个一个context,它会有两个方法Provider和Consumer,功能如同字义,一个是提供者,就是数据的发起者,一个是消费者,就是数据的接受者

createContext生成的Provider对应Cosumer是一对,所以需要创建一个JS文件,将生成的两者导出,我们才能更好的在不同文件下使用

import { Component, createContext } from "react";
const { Consumer: MyConsumer, Provider: MyProvider } = createContext()
export { MyConsumer, MyProvider }

创建一个 最外层文件App.js -> 父级文件Wrap.js -> 子级文件Inner.js

App.js

ReactDOM.render(<MyProvider value={{a: 1}}><Wrap/></MyProvider>, document.getElementById("root"))

Wrap.js

import { Component } from "react";
import Inner from './Inner'
class Wrap extends Component {
    render() {
        return <Inner></Inner>
    }
}
export default Wrap
import { Component } from "react";
import {MyConsumer} from './Provider'
class Inner extends Component {
    render() {
        return <MyConsumer>
            {(context) => { console.log(context); }}
        </MyConsumer>
    }
}

export default Inner

就可以看见在Inner组件中得到并输出了由最外层的context数据,而不是通过像props需要一层一层的传递下来的 

我们也可以对Provider和Consumer进行封装导出

import { Component, createContext } from "react";
const { Consumer: MyConsumer, Provider } = createContext()
class MyProvider extends Component {
    render() {
        // ...
        return <Provider value={{...this.props.value}}>
            ...
            {this.props.children}
            ...
        </Provider>
    }
}

export { MyConsumer, MyProvider }

过时的API(16.3版本前)

废弃原因:当消费者组件A改变context内容时,如果中间组件B不依赖context,那么shouldComponentUpdate就不会发觉变化,如果返回了false,就不会rerender,最终导致后面的依赖context的子组件也不会rerender,这不是我们想要的结果。而新版API会有穿透的能力

使用方式:组件添加 childContextTypes 和 getChildContext,那么它下面的所有组件都能通过contextTypes获取到context

class MessageList extends React.Component {
  getChildContext() {
    return {color: "red"};
  }

  render() {
    return <Message />;
  }
}

MessageList.childContextTypes = {
  color: PropTypes.string
};
class Message extends React.Component {
  // B如果不依赖context,就可能影响下面子组件的rerender
  // shouldComponentUpdate(nextProps, prevState) {
  //  if (...) {
  //      return false;
  //  }
  //  return true;
  // }
  render() {
    return <Button>点击</Button>
  }
}
class Button extends React.Component {
  render() {
    return (
      // 通过this.context访问
      <button style={{background: this.context.color}}>
        {this.props.children}
      </button>
    );
  }
}
// 子孙组件可通过contextTypes就能获取到context
Button.contextTypes = {
  color: PropTypes.string
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值