• React高级特性之Context


    Context提供了一种不需要手动地通过props来层层传递的方式来传递数据。

    正文

    在典型的React应用中,数据是通过props,自上而下地传递给子组件的。但是对于被大量组件使用的固定类型的数据(比如说,本地的语言环境,UI主题等)来说,这么做就显得十分的累赘和笨拙。Context提供了一种在组件之间(上下层级关系的组件)共享这种类型数据的方式。这种方式不需要你手动地,显式地通过props将数据层层传递下去。

    什么时候用Context?

    这一小节,讲的是context适用的业务场景。

    Context是为那些可以认定为【整颗组件树范围内可以共用的数据】而设计的。比如说,当前已认证的用户数据,UI主题数据,当前用户的偏好语言设置数据等。举个例子,下面的代码中,为了装饰Button component我们手动地将一个叫“theme”的prop层层传递下去。 传递路径是:App -> Toolbar -> ThemedButton -> Button

    class App extends React.Component {
       
      render() {
       
        return <Toolbar theme="dark" />;
      }
    }
    
    function Toolbar(props) {
       
      // The Toolbar component must take an extra "theme" prop
      // and pass it to the ThemedButton. This can become painful
      // if every single button in the app needs to know the theme
      // because it would have to be passed through all components.
      return (
        <div>
          <ThemedButton theme={
       props.theme} />
        </div>
      );
    }
    
    class ThemedButton extends React.Component {
       
      render() {
       
        return <Button theme={
       this.props.theme} />;
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    使用context,我们可以跳过层层传递所经过的中间组件。现在我们的传递路径是这样的:App -> Button

    // Context lets us pass a value deep into the component tree
    // without explicitly threading it through every component.
    // Create a context for the current theme (with "light" as the default).
    const ThemeContext = React.createContext('light');
    
    class App extends React.Component {
       
      render() {
       
        // Use a Provider to pass the current theme to the tree below.
        // Any component can read it, no matter how deep it is.
        // In this example, we're passing "dark" as the current value.
        return (
          <ThemeContext.Provider value="dark">
            <Toolbar />
          </ThemeContext.Provider>
        );
      }
    }
    
    // A component in the middle doesn't have to
    // pass the theme down explicitly anymore.
    function Toolbar(props) {
       
      return (
        <div>
          <ThemedButton />
        </div>
      );
    }
    
    class ThemedButton extends React.Component {
       
      // Assign a contextType to read the current theme context.
      // React will find the closest theme Provider above and use its value.
      // In this example, the current theme is "dark".
      static contextType = ThemeContext;
      render() {
       
        return <Button theme={
       this.context} />;
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

    在你用Context之前

    这一小节,讲的是我们要慎用context。在用context之前,我们得考虑一下当前的业务场景有没有第二种技术方案可用。只有在确实想不出来了,才去使用context。

    Context主要用于这种业务场景:大量处在组件树不同层级的组件需要共享某些数据。实际开发中,我们对context要常怀敬畏之心,谨慎使用。因为它犹如潘多拉的盒子,一旦打开了,就造成很多难以控制的现象(在这里特指,context一旦滥用了,就会造成很多组件难以复用)。参考React实战视频讲解:进入学习

    如果你只是单纯想免去数据层层传递时对中间层组件的影响,那么组件组合是一个相比context更加简单的技术方案。

    举个例子来说,假如我们有一个叫Page的组件,它需要将useravatarSize这两个prop传递到下面好几层的Link组件和Avatar组件:

    <Page user={
       user} avatarSize={
       avatarSize} />
    // ... which renders ...
    <PageLayout user={
       user} avatarSize={
       avatarSize} />
    // ... which renders ...
    <NavigationBar user={
       user} avatarSize={
       avatarSize} />
    // ... which renders ...
    <Link href={
       user.permalink}>
      <Avatar user={
       user} size={
       avatarSize} />
    </Link>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    我们大费周章地将useravatarSize这两个prop传递下去,最终只有Avatar组件才真正地用到它。这种做法显得有点低效和多余的。假如,到后面Avatar组件需要从顶层组件再获取一些格外的数据的话,你还得手动地,逐层地将这些数据用prop的形式来传递下去。实话说ÿ

  • 相关阅读:
    【程序进程及相关命令】
    VMware VCP-DCV认证课程概述
    NGINX监听IPV6
    Typora for Mac:打造全新文本编辑体验
    Python 面向对象1-类、对象、属性
    拼多多商品详情api接口
    OpenGL概述(核心模式与立即模式、扩展、OpenGL中的对象)
    NEFU算法设计与分析课程设计
    工具篇 | 05 | IntelliJ IDEA
    C语言 字符函数汇总,模拟实现各字符函数(炒鸡详细)
  • 原文地址:https://blog.csdn.net/grooyo/article/details/127767342