• React与ES6(四)ES6如何处理React mixins


    React与ES6系列:

    1. React与ES6(一)开篇介绍
    2. React和ES6(二)ES6的类和ES7的property initializer
    3. React与ES6(三)ES6类和方法绑定
    4. React与ES6(四)ES6如何处理React mixins

    在使用React.createClass()的时候你也许使用过一个所谓的mixin的东西。使用它,你可以给React组件天剑很多其他的功能。这个概念不止用在React上,也用在很多其他的编程语言或者框架上。

    在ES6中不能够在使用React的mixin机制。本文不会纠结于原因为何。我们只关注ES6中的替代方法。

    High-Order Component

    或者可以叫做高阶组件。

    我们使用前文中使用的CartItem组件作为例子,在其中显示一个每秒计数增加1的timer。

    为了更好的演示,我们不修改CartItem的代码。相反的我们要提供一些组件,这些组件会封装CartItem并且给CartItem增强一些另外的方法。这样的一个组件就叫做High-Order Comoentn

    上面的介绍可能还是有些模糊,不要紧随着本文步步深入一切都会变得清晰。

    我们假设这个Hight-Order Component叫做IntervalEnhance,存放在一个叫做intervalEnhance.jsx的文件中。那么我们的CartItem应该怎么改呢?

    import React from 'react';
    // 1
    import {IntervalEnhance} from './IntervalEnhance';
    
    class CartItem extends React.Component {
        //...略...
    }
    //2
    export default IntervalEnhance(CartItem);
    

    解释:

    1. 引入高阶组件IntervalEnhance
    2. export高阶组件包装增强后的CartItem

    下满就看看告诫组件是怎么定义的:

    //@flow
    
    import React from 'react';
    //1
    export var IntervalEnhance = ComposeComponent => class extends ComposeComponent {
        // 2
        static displayName = 'ComponentEnhancedWithIntervalHOC';
    
        constructor(props) {
            super(props);
            this.state = {
                seconds: 0
            };
        }
        // 3
        componentDidMount() {
            this.interval = setInterval(this.tick.bind(this), 1000);
        }
        // 3
        componentWillUnmount() {
            clearInterval(this.interval);
        }
    
        tick() {
            this.setState({
                seconds: this.state.seconds + 1000
            });
        }
    
        render() {
            return (
                // 4
                <ComposeComponent {...this.props} {...this.state} />
            );
        }
    }
    

    解释:

    1. ComposeComponent => class extends React.Comonent这句。还记得箭头函数吗?没错,这就是一个箭头函数。这个函数接受一个组件为输入参数,返回一个类。ComposedComponent就是输入参数,也就是需要包装增强的组件。export var IntervalEnhance就是把前面定义的函数命名为IntervalEnhance export出去给其他的模块使用。
    2. displayName设定为ComponentEnhancedWithIntervalHOC是为了在DevTools中方便调试。在DevTools里这个组件就会被叫做ComponentEnhancedWithIntervalHOC
    3. 组件生命周期不同阶段的回调。是React组件的内置方法。
    4. 最有意思的就是这里了。这样的写法会把当前高阶组件的全部props和state都发送给CartItem,这样CartItem就可以取到this.state.seconds属性的值了。

    最后我们就需要修改CartItem组件的内部了。这样才能输出this.state.seconds的值。

    import React from 'react';
    
    import {IntervalEnhance} from './IntervalEnhance';
    
    class CartItem extends React.Component {
    
        render() {
            return (
                <article className="row large-4">
    
                    <p className="large-12 column" >
                        <strong>Time elapsed for interval: </strong>
                        {this.props.seconds} ms
                    </p>
    
                </article>
            );
        }
    }
    

    注意:全部都完成都不需要修改CartItem组件本身(除了render方法)!这就是为什么High-Order Component为什么这里厉害的原因所在。

    使用ES7装饰器

    使用ES7的装饰器(decorator)代码会更加简洁。

    首先,安装babel-plugin-transform-decorators-legacy:

    npm install --save-dev babel-plugin-transform-decorators-legacy
    

    之后,配置.babelrc文件:

    {
        "presets": ["es2015", "react", "stage-0"],
        "plugins": [
            ["transform-decorators-legacy"]
        ]
    }
    

    然后:

    import React from 'react';
    
    import {IntervalEnhance} from './intervalEnhance';
    
    @IntervalEnhance
    class CartItem extends React.Component {
        // ...略...
    }
    

    总结

    Hight-Order Component(高阶组件)非常好用,也可以非常有效的解决问题。当前,使用高阶组件非常多的用来代替旧的mixin。

    有一个典型的例子就是Relay。Relay也是facebook发布的一个完全基于React的framework。你的每一个组件都可以包裹在Relay容器中,自动的存取依赖的数据。

  • 相关阅读:
    网站调整为黑白的方法
    滚动条样式优化
    js点击页面其他地方如何隐藏div元素菜单
    微信分享网页时自定义标题、描述和图片
    纯CSS3美化单选按钮radio
    纯CSS3实现圆形进度条动画
    解决checkbox的attr(checked)一直为undefined问题
    jQuery – 鼠标经过(hover)事件的延时处理
    PC版模块滚动不显示滚动条效果
    上传文件样式美化
  • 原文地址:https://www.cnblogs.com/sunshine-anycall/p/5888288.html
Copyright © 2020-2023  润新知