React的context就是一个全局变量,可以从根组件跨级别在React的组件中传递。React context的API有两个版本,React16.x之前的是
老版本的context,之后的是新版本的context。

1.老版本的context

getChildContext 根组件中声明,一个函数,返回一个对象,就是context
childContextTypes 根组件中声明,指定context的结构类型,如不指定,会产生错误
contextTypes 子孙组件中声明,指定要接收的context的结构类型,可以只是context的一部分结构。contextTypes 没有定义,context将是一个空对象。
this.context 在子孙组件中通过此来获取上下文
(注:从React v15.5开始 ,React.PropTypes 助手函数已被弃用,可使用 prop-types 库 来定义contextTypes)

举例如下:

  1. //根组件
  2. class MessageList extends React.Component {
  3. getChildContext() {
  4. return {color: "purple",text: "item text"};
  5. }
  6.  
  7. render() {
  8. const children = this.props.messages.map((message) =>
  9. <Message text={message.text} />
  10. );
  11. return <div>{children}</div>;
  12. }
  13. }
  14.  
  15. MessageList.childContextTypes = {
  16. color: React.PropTypes.string
  17. text: React.PropTypes.string
  18. };
  19.  
  20. //中间组件
  21. class Message extends React.Component {
  22. render() {
  23. return (
  24. <div>
  25. <MessageItem />
  26. <Button>Delete</Button>
  27. </div>
  28. );
  29. }
  30. }
  31.  
  32. //孙组件(接收组件)
  33. class MessageItem extends React.Component {
  34. render() {
  35. return (
  36. <div>
  37. {this.context.text}
  38. </div>
  39. );
  40. }
  41. }
  42.  
  43. MessageItem.contextTypes = {
  44. text: React.PropTypes.string
  45. };
  46.  
  47. class Button extends React.Component {
  48. render() {
  49. return (
  50. <button style={{background: this.context.color}}>
  51. {this.props.children}
  52. </button>
  53. );
  54. }
  55. }
  56.  
  57. Button.contextTypes = {
  58. color: React.PropTypes.string
  59. };

2.新版本的context

新版本的React context使用了Provider和Customer模式,和react-redux的模式非常像。在顶层的Provider中传入value,
在子孙级的Consumer中获取该值,并且能够传递函数,用来修改context,如下代码所示:

  1. //创建Context组件
  2. const ThemeContext = React.createContext({
  3. theme: 'dark',
  4. toggle: () => {}, //向上下文设定一个回调方法
  5. });
  6.  
  7. //运行APP
  8. class App extends React.Component {
  9. constructor(props) {
  10. super(props);
  11.  
  12. this.toggle = () => { //设定toggle方法,会作为context参数传递
  13. this.setState(state => ({
  14. theme:
  15. state.theme === themes.dark
  16. ? themes.light
  17. : themes.dark,
  18. }));
  19. };
  20.  
  21. this.state = {
  22. theme: themes.light,
  23. toggle: this.toggle,
  24. };
  25. }
  26.  
  27. render() {
  28. return (
  29. <ThemeContext.Provider value={this.state}> //state包含了toggle方法
  30. <Content />
  31. </ThemeContext.Provider>
  32. );
  33. }
  34. }
  35.  
  36. //中间组件
  37. function Content() {
  38. return (
  39. <div>
  40. <Button />
  41. </div>
  42. );
  43. }
  44.  
  45. //接收组件
  46. function Button() {
  47. return (
  48. <ThemeContext.Consumer>
  49. {({theme, toggle}) => (
  50. <button
  51. onClick={toggle} //调用回调
  52. style={{backgroundColor: theme}}>
  53. Toggle Theme
  54. </button>
  55. )}
  56. </ThemeContext.Consumer>
  57. );
  58. }

详细用法可以参考官方文档:https://react.docschina.org/docs/context.html#reactcreatecontext

3. context在如下的生命周期钩子中可以使用

constructor(props, context)
componentWillReceiveProps(nextProps, nextContext)
shouldComponentUpdate(nextProps, nextState, nextContext)
componentWillUpdate(nextProps, nextState, nextContext)
componentDidUpdate(prevProps, prevState, prevContext)

4. 在无状态组件中可以通过参数传入

  1. function D(props, context) {
  2. return (
  3. <div>{this.context.user.name}</div>
  4. );
  5. }
  6.  
  7. D.contextTypes = {
  8. user: React.PropTypes.object.isRequired
  9. }

5. React context的局限性

1. 在组件树中,如果中间某一个组件 ShouldComponentUpdate returning false 了,会阻碍 context 的正常传值,导致子组件无法获取更新。
2. 组件本身 extends React.PureComponent 也会阻碍 context 的更新。

注意点:

1. Context 应该是唯一不可变的
2. 组件只在初始化的时候去获取 Context

参考:https://www.tuicool.com/articles/nUryimf
     https://segmentfault.com/a/1190000012575622

React context基本用法的更多相关文章

  1. React Context 的用法

    在React的官方文档中,Context被归类为高级部分(Advanced),属于React的高级API,但官方并不建议在稳定版的App中使用Context. The vast majority of ...

  2. 你不可不知的 React Native 混合用法(Android 篇)

    前言 当前 React Native 虽说版本更新比较快,各种组件也提供的很全面了,但是在某些情况下,混合开发的方式才会快速缩短开发周期,原因无非就是原生平台的"底蕴"无疑更深,拥 ...

  3. React Context API

    使用React 开发程序的时候,组件中的数据共享是通过数据提升,变成父组件中的属性,然后再把属性向下传递给子组件来实现的.但当程序越来越复杂,需要共享的数据也越来越多,最后可能就把共享数据直接提升到最 ...

  4. [React]Context机制

    在React中,Context机制是为了方便在组件树间传递数据. 例子 import React from 'react' const themes={ light:"亮色主题", ...

  5. [React] Prevent Unnecessary Rerenders of Compound Components using React Context

    Due to the way that React Context Providers work, our current implementation re-renders all our comp ...

  6. 探索 Redux4.0 版本迭代 论基础谈展望(对比 React context)

    Redux 在几天前(2018.04.18)发布了新版本,6 commits 被合入 master.从诞生起,到如今 4.0 版本,Redux 保持了使用层面的平滑过渡.同时前不久, React 也从 ...

  7. React Hooks +React Context vs Redux

    React Hooks +React Context vs Redux https://blog.logrocket.com/use-hooks-and-context-not-react-and-r ...

  8. [译]React Context

    欢迎各位指导与讨论 : ) 前言 由于笔者英语和技术水平有限,有不足的地方恳请各位指出.我会及时修正的 O(∩_∩)O 当前React版本 15.0.1 时间 2016/4/25 正文 React一个 ...

  9. React的组件用法

    React.createClass() 中文翻译 https://discountry.github.io/react/3.4K ( https://doc.react-china.org868 ) ...

随机推荐

  1. Spring笔记2

    Bean生命周期 1 实例化 2 注入属性 3 BeanNameAware 4 BeanFactoryAware 5 ApplicationContextAware 6 BeanPostProcess ...

  2. go web处理上传

    要使表单能够上传文件,第一步就是添加form的enctype属性,enctype属性有如下三种情况: application/x-www-form-urlencoded 表示在发送前编码所有字符(默认 ...

  3. 静态栈抽象数据类型stack实现

    #include<stdio.h> #include<stdbool.h> #include<stdlib.h> #define MAX_STACK_SIZE 10 ...

  4. 文件 I/O字节流

    输入字节流: import java.io.*; public class test_main { public static void main(String[] args) { int n=-1; ...

  5. R语言学习笔记(十五):获取文件和目录信息

    file.info() 参数是表示文件名称的字符串向量,函数会给出每个文件的大小.创建时间.是否为目录等信息. > file.info("z.txt") size isdir ...

  6. JOI2017 春季合宿:Railway Trip

    自己的AC做法似乎离正解偏了十万八千里而且复杂了不少--不管怎样还是记录下来吧. 题意: 题目链接: JOISC2017 F - AtCoder JOISC2017 F - LOJ \(N\)个车站排 ...

  7. jsp中的input

    Input表示Form表单中的一种输入对象,其又随Type类型的不同而分文本输入框,密码输入框,单选/复选框,提交/重置按钮等,下面一一介绍. 1,type=text 输入类型是text,这是我们见的 ...

  8. WPF中,如何将绑定源设置到单件实例

    原文:WPF中,如何将绑定源设置到单件实例  WPF中,如何将绑定源设置到单件实例                                       周银辉 大概两个月前,曾有位朋友问我:如 ...

  9. 初步学习pg_control文件之十一

    接前文  初步学习pg_control文件之十,再看这个 XLogRecPtr prevCheckPoint; /* previous check point record ptr */ 发生了che ...

  10. [Windows]_[C/C++]_[如何调试子进程]

    场景 1.VC++ 的程序A在启动程序C时, 如果需要调试程序C的话一般有两种, 一种是通过菜单 调试->附加到进程的方式来调试程序, 缺点就是这个进程必须先启动, 但是一启动的话有可能就执行了 ...