为什么React不再使用Mixin

2,029 阅读3分钟

虽然组件的原则就是模块化,彼此之间相互独立,但是有时候不同的组件之间可能会共用一些功能,共享一部分代码。所以 React 提供了 mixins 这种方式来处理这种问题(主要用于使用 createReactClass 创建 React 组件)。

Mixin 就是用来定义一些方法,使用这个 mixin 的组件能够自由的使用这些方法(就像在组件中定义的一样),所以 mixin 相当于组件的一个扩展,在 mixin 中也能定义“生命周期”方法。

比如一个定时器的 mixin:

var SetIntervalMixin = {
    componentWillMount: function() {
        this.intervals = [];
    },
    setInterval: function() {
        this.intervals.push(setInterval.apply(null, arguments));
    },
    componentWillUnmount: function() {
        this.intervals.map(clearInterval);
    }
};

var TickTock = React.createClass({
    mixins: [SetIntervalMixin], // Use the mixin
    getInitialState: function() {
        return {seconds: 0};
    },
    componentDidMount: function() {
        this.setInterval(this.tick, 1000); // Call a method on the mixin
    },
    tick: function() {
        this.setState({seconds: this.state.seconds + 1});
    },
    render: function() {
        return (
            <p>
                React has been running for {this.state.seconds} seconds.
            </p>
        );
    }
});

React.render(
    <TickTock />,
    document.getElementById('example')
);

React 的 mixins 的强大之处在于,如果组件拥有多个 mixins,且这些 mixins 中定义了相同的生命周期方法(例如,当组件被销毁时,几个 mixins 都想要进行一些清理工作),那么这些生命周期方法都会被调用的。使用 mixins 时,mixins 会先按照定义时的顺序执行,最后调用组件上对应的方法。

使用 ES6 class 定义的组件已经不支持 mixin 了,因为使用 mixin 的场景都可以用组合组件这种模式来做到(参见 Mixins Are Dead. Long Live Compositionzh-hans.reactjs.org/blog/2016/0…

Mixins在React中的使用是非显示的、混乱的,Mixins可以使用React中声明的方法,反之亦可。

比如一个mixin引用了组件中的状态,状态改变时,你能记起混入的mixin也引用了state吗?即使假设你发现了mixin中使用了该state,又如何知道并修改另外一个引用了该mixin的组件?更或者,当你想到追踪组件混入的mixin方法,发现mixin嵌套的层级是♾的:​永远不知道为一个mixin添加方法会带来什么后果,可能和组件内方法出现命名冲突等。为了解决这些问题,react为我们推荐了HOC高阶组件(函数式编程模式,从一个组件包装成另一个组件)的方法:

举个栗子:

1、创建被包装组件:​2、解锁🔓包装方法:​3、接下来简单修改List组件:​4、最后:

HOC的优势:

组件并不会收到任何入侵,在HOC中,组件与功能是解耦的。HOC可以应用到任何组件,组件也可以被任何HOC包裹📦,非常灵活。

另外,mixin应用了面向对象的概念,在JS中有种硬拗的感觉;HOC是声明式的,体现了函数式编程的思想,符合现代JS的编程理念。

HOC存在的问题:

  • 嵌套地狱,无意义嵌套

  • 不要轻易更改HOC嵌套的顺序

  • props传递的问题

    props在传递的过程中,可能被每一层的HOC加工,互相之间不知道对方做了什么,如:

Hooks

为了解决组件间复用逻辑的问题,既不会像Mixin一样入侵组件,也不会像HOC那样打乱组件的结构。它可以以自然的方式,将逻辑从组件中提取出来。

在大多数情况下,Hooks都是可以取代Mixin和HOC的。