美文网首页
古老的React mixins

古老的React mixins

作者: DC_er | 来源:发表于2019-04-27 20:54 被阅读0次

    今天在翻看博客时,忽然发现有的博主在讨论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(高阶组件)

    相关文章

      网友评论

          本文标题:古老的React mixins

          本文链接:https://www.haomeiwen.com/subject/gmrlnqtx.html