资讯专栏INFORMATION COLUMN

React中的Context怎么用

zhouzhou / 1867人阅读

摘要:怎样使用假设有个如下的结构上面的例子中,我们把手动的方式传给了,这期间穿越了,而对本身没有什么用。不建议使用绝大多数的应用程序是不需要使用的。如果项目对数据管理较为复杂,推荐使用类似于或这样的状态管理库,而不要使用。

What is Context

今天在学习styled-components的Theming时,关于styled-components对主题的实现与管理上提到,主要应用到了react的context API,所以好好研读了一下官方文档,对该API做了如下记录。

什么是Context

当我们使用React时,很容易的通过观察组件的props来跟踪组件间的数据流流向,这种跟踪观察方式也让我们很容易的去理解组件。

而有的时候,我们不想让一个props从最外层,通过组件一层一层的传递到目标组件上,这时就可以通过context来直接实现我们希望的操作。

怎样使用Context

假设有个如下的结构:

class Button extends React.Component {
  render() {
    return (
      
    );
  }
}

class Message extends React.Component {
  render() {
    return (
      
{this.props.text}
); } } class MessageList extends React.Component { render() { const color = "purple"; const children = this.props.messages.map((message) => ); return
{children}
; } }

上面的例子中,我们把color手动的方式传给了Button,这期间穿越了Message,而对Message本身没有什么用。如果用context的话,可以直接给到Button组件上,如下:

const PropTypes = require("prop-types");

class Button extends React.Component {
  render() {
    return (
      
    );
  }
}

Button.contextTypes = {
  color: PropTypes.string
};

class Message extends React.Component {
  render() {
    return (
      
{this.props.text}
); } } class MessageList extends React.Component { getChildContext() { return {color: "purple"}; } render() { const children = this.props.messages.map((message) => ); return
{children}
; } } MessageList.childContextTypes = { color: PropTypes.string };

通过给MessageList(Context宿主)添加childContextTypesgetChildContext,可以实现在该组件子结构下的所有组件(e.g. Button)直接通过定义contextTypes来获取。

如果未定义contextTypes的话,context是一个空对象。

可获取Context对象的勾子函数

一旦组件定义了contextTypes以后,以下的勾子中就会得到一个附加的参数——context对象:

constructor(props, context)

componentWillReceiveProps(nextProps, nextContext)

shouldComponentUpdate(nextProps, nextState, nextContext)

componentWillUpdate(nextProps, nextState, nextContext)

componentDidUpdate(prevProps, prevState, prevContext)

无状态组件获取Context方法

无状态组件同样可以通过给函数定义contextTypes属性的方式,让组件拥有获取context的能力,例如:

const PropTypes = require("prop-types");

const Button = ({children}, context) =>
  ;

Button.contextTypes = {color: PropTypes.string};
Context的更新

不要更新Context!

React虽然有提供关于更新context的API,但不建议去使用。

如果想用的话,可以看下面的这个例子。
getChildContext方法会在stateprops更新时被调用,可以通过局部状态的更新进而来更新context。当context更新后,所有的子组件都能接到新值。

const PropTypes = require("prop-types");

class MediaQuery extends React.Component {
  constructor(props) {
    super(props);
    this.state = {type:"desktop"};
  }

  getChildContext() {
    return {type: this.state.type};
  }

  componentDidMount() {
    const checkMediaQuery = () => {
      const type = window.matchMedia("(min-width: 1025px)").matches ? "desktop" : "mobile";
      if (type !== this.state.type) {
        this.setState({type});
      }
    };

    window.addEventListener("resize", checkMediaQuery);
    checkMediaQuery();
  }

  render() {
    return this.props.children;
  }
}

MediaQuery.childContextTypes = {
  type: PropTypes.string
};

这里有个问题是,如果宿主组件的context更新了,其下使用该context的子组件可能因为某个父组件的shouldComponentUpdate返回false而不做状态更新。这就完全不符合通过使用context来控制组件状态更新的初衷,所以证明使用context来管理组件状态不太靠谱。
这里有篇博客关于介绍如何安全的使用context的。

不建议使用Context

绝大多数的应用程序是不需要使用context的。

如果你想要你的应用稳定,就不要使用它,这是一个实验性的API,在未来的版本更新中很有可能会被弃掉。

context最好的使用场景是隐式的传入登录的用户,当前的语言,或者主题信息。要不然所有这些可能就是全局变量,但是context让你限定他们到一个多带带的React树里。

如果项目对数据管理较为复杂,推荐使用类似于redux或mobX这样的状态管理库,而不要使用context

记录的过程是一种成长,欢迎大家关注我的github。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/88737.html

相关文章

  • React 328道最全面试题(持续更新)

    摘要:希望大家在这浮夸的前端圈里,保持冷静,坚持每天花分钟来学习与思考。 今天的React题没有太多的故事…… 半个月前出了248个Vue的知识点,受到很多朋友的关注,都强烈要求再出多些React相前的面试题,受到大家的邀请,我又找了20多个React的使用者,他们给出了328道React的面试题,由我整理好发给大家,同时发布在了前端面试每日3+1的React专题,希望对大家有所帮助,同时大...

    kumfo 评论0 收藏0
  • 高阶组件 + New Context API = ?

    摘要:但是老版的存在一个严重的问题子孙组件可能不更新。其中,某一时刻属性发生变化导致组件触发了一次渲染,但是由于组件是且并未用到属性,所以的变化不会触发及其子孙组件的更新,导致组件未能得到及时的更新。 1. 前言 继上次小试牛刀尝到高价组件的甜头之后,现已深陷其中无法自拔。。。那么这次又会带来什么呢?今天,我们就来看看【高阶组件】和【New Context API】能擦出什么火花! 2. N...

    Joyven 评论0 收藏0
  • 从Preact了解一个类React的框架是怎么实现的(三): 组件

    摘要:组件渲染首先我们来了解组件返回的虚拟是怎么渲染为真实,来看一下的组件是如何构造的可能我们会想当然地认为组件的构造函数定义将会及其复杂,事实上恰恰相反,的组件定义代码极少。 前言   首先欢迎大家关注我的掘金账号和Github博客,也算是对我的一点鼓励,毕竟写东西没法获得变现,能坚持下去也是靠的是自己的热情和大家的鼓励。  之前分享过几篇关于React的文章: React技术内幕: k...

    AlphaWatch 评论0 收藏0
  • React中的“虫洞”——Context

    摘要:理论上,通过一层层传递下去当然是没问题的。不过这也太麻烦啦,要是能在最外层和最里层之间开一个穿越空间的虫洞就好了。使用看起来很高大上的使用起来却异常简单。就像中的全局变量,只有真正全局的东西才适合放在中。 当我们写React时,我们总是通过改变State和传递Prop对view进行控制,有时,也会遇到一点小麻烦。 背景 但是随着我们的应用变的越来越复杂,组件嵌套也变的越来越深,有时甚至...

    muddyway 评论0 收藏0
  • React context 丢失问题

    摘要:丢失问题文本是为了说清目前的机制是而不是我们以为的机制,并说明这两者的区别。虽然明白了原理,但是问题并没有解决。上下文注意这里是,需要执行接受回调函数,回调函数中的内容为实测可以成功拿到。 React context 丢失问题 文本是为了说清react context目前的机制是owner context 而不是我们以为的parent context 机制,并说明这两者的区别。...

    Seay 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<