古老的React mixins

今天在翻看博客时,忽然发现有的博主在讨论render props时,说到了React mixins。由于自己使用React时间不是特别长,所以对于早前的React版本的语法不是很熟悉,所以补充一下。顺便做一个小的系列文章:

  1. 古老的React mixins
  2. HOC(高阶组件)
  3. render props
  4. React Hooks

什么是React mixins ?

mixins(混合)是指定义一个对象,让组件去继承该对象的方法和状态的过程,该对象也被称为混入(混合)对象。若组件和被继承的混合对象具有相同的生命钩子函数,并且在执行该生命钩子函数时,混合对象的函数会优先执行,然后再到组件内相同函数执行,但仅限于生命钩子函数。

另外,组件内不允许有和混合对象相同命名的方法(非生命钩子函数),如例子中的handlAction,否则会报错:

ReactClassInterface: You are attempting to define `handlAction` on your component more than once. This conflict may be due to a mixin.
// 混合
const mixinCommon = {
    componentWillMount: function() {
        console.log("mix componentWillMount!");    //优先执行
    },
    handlAction:function(){
        console.log("mix action!");     //该方法不允许再从组件中重构,否则会报错
    }
}

var HelloWorld = React.createClass({
    mixins: [mixinCommon],
    componentWillMount: function() {
        console.log("HelloWorld componentWillMount!"); //仍会执行
    },
    componentDidMount: function() {
            this.handlAction();      //调用mixinCommon的方法
        },
        render: function() {
            return <h1>Hello World!</h1>;
        }
});
ReactDOM.render(<HelloWorld />,document.getElementById("example"));

需要注意的是:ES6 本身是不包含混入支持的。因此,如果你使用 class 关键字创建组件,那就不能使用混入功能了。我们现在在使用React的时候大部分都是使用class关键字创建组件,很少使用createClass来创建组件了。正因为如此,我们现在几乎很少使用到mixins了。

React mixins在解决什么问题,本身存在什么问题 ?

回答上述问题之前,我们再来看一个mixins的典型🌰:

import React from 'react'
import ReactDOM from 'react-dom'

// mixin 中含有了你需要在任何应用中追踪鼠标位置的样板代码。
// 我们可以将样板代码放入到一个 mixin 中,这样其他组件就能共享这些代码
const MouseMixin = {
  getInitialState() {
    return { x: 0, y: 0 }
  },

  handleMouseMove(event) {
    this.setState({
      x: event.clientX,
      y: event.clientY
    })
  }
}

const App = React.createClass({
  mixins: [ MouseMixin ],
  
  render() {
    const { x, y } = this.state

    return (
      <div style={{ height: '100%' }} onMouseMove={this.handleMouseMove}>
        <h1>The mouse position is ({x}, {y})</h1>
      </div>
    )
  }
})

ReactDOM.render(<App/>, document.getElementById('app'));

很简单,如果有好几处地方需要使用鼠标的X和Y坐标,只需要轻松的将 MouseMixin 混入他们的组件中,并通过 this.state 属性获得鼠标的 x 和 y 坐标。所以mixin很显然是为了解决代码复用的问题。

但是这种解决方式并不是非常完美无瑕,具体原因总结如下:

  • ES6 class不支持 mixins。
  • 不够直接。minxins 改变了 state,因此也就很难知道一些 state 是从哪里来的,尤其是当不止存在一个 mixins 时。
  • 名字冲突。两个要更新同一段 state 的 mixins 可能会相互覆盖。createClass API 会对两个 mixins 的 getInitialState 是否具有相同的 key 做检查,如果具有,则会发出警告,但该手段并不牢靠。

所以为了解决上述问题,在React社区有人开始大量使用高阶组件HOC。参考下篇文章:React HOC(高阶组件)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 作为一个合格的开发者,不要只满足于编写了可以运行的代码。而要了解代码背后的工作原理;不要只满足于自己的程序...
    六个周阅读 12,716评论 1 33
  • 深入JSX date:20170412笔记原文其实JSX是React.createElement(componen...
    gaoer1938阅读 12,480评论 2 35
  • 40、React 什么是React?React 是一个用于构建用户界面的框架(采用的是MVC模式):集中处理VIE...
    萌妹撒阅读 4,756评论 0 1
  • 这篇笔记主要包含 Vue 2 不同于 Vue 1 或者特有的内容,还有我对于 Vue 1.0 印象不深的内容。关于...
    云之外阅读 10,489评论 0 29
  • 事件系统 合成事件的绑定方式 Test 合成事件的实现机制:事件委派和自动绑定。 React合成事件系统的委托机制...
    cheneyg916阅读 3,064评论 0 1

友情链接更多精彩内容