资讯专栏INFORMATION COLUMN

『译』React Mixin 的使用

张巨伟 / 1286人阅读

摘要:可以说,相比继承而已,更喜欢这种组合的方式。需要指出的是,是可以包含在其他的中的程序会在控制台打印出。包含多个我们的要包裹在数组当中,提醒了我们可以在组件中包含多个注意事项这里有几件事需要引起我们的注意,当我们使用的时候。

update: Mixin 只适用于 ES5。如果你的项目里面用的是 ES6 ,可以采用高阶组件来实现 Mixin 的功能。

我使用 React.js 构建大型项目已经有一段时间了,我遇到过很多在不同的组件中都要用到相同功能的情况。因此,我花了一个小时左右的时间去了解mixin的用法,然后分享我所学习到的一些东西。

为什么使用 Mixin ?

React回避子类组件,但是我们知道,到处重复地编写同样的代码是不好的。所以为了将同样的功能添加到多个组件当中,你需要将这些通用的功能包装成一个mixin,然后导入到你的模块中。 可以说,相比继承而已,React更喜欢这种组合的方式。嗯,我也喜欢这样。

写一个简单的 Mixin

现在假设我们在写一个app,我们知道在某些情况下我们需要在好几个组件当中设置默认的name属性。
现在,我们不再是像以前一样在每个组件中写多个同样的getDefaultProps方法,我们可以像下面一样定义一个mixin

var DefaultNameMixin = {
    getDefaultProps: function () {
        return {name: "Skippy"};
    }
};

它没什么特殊的,就是一个简单的对象而已。

加入到 React 组件中

为了使用mixin,我们只需要简单得在组件中加入mixins属性,然后把刚才我们写的mixin包裹成一个数组,将它作为该属性的值即可:

var ComponentOne = React.createClass({
    mixins: [DefaultNameMixin],
    render: function() {
    return 

Hello {this.props.name}

; } }); React.renderComponent(, document.body);

JSFiddle 示例:一个简单的 mixin 例子

重复使用

就像你想象的那样,我们可以在任何其他组件中包含我们的mixin

var ComponentTwo = React.createClass({
    mixins: [DefaultNameMixin],
    render: function () {
        return (
            

{this.props.name}

Favorite food: {this.props.food}

); } });

JSFiddle 示例:在多个组件中使用同一个 mixin

生命周期方法会被重复调用!

如何你的mixin当中包含生命周期方法,不要焦急,你仍然可以在你的组件中使用这些方法,而且它们都会被调用:

JSFiddle 示例:展示了两个 default props 都会被设置

两个getDefaultProps方法都将被调用,所以我们可以得到默认为Skippyname属性和默认为Pancakesfood属性。任何一个生命周期方法或属性都会被顺利地重复调用,但是下面的情况除外:

render:包含多个render方法是不行的。React 会跑出异常:

Uncaught Error: Invariant Violation: ReactCompositeComponentInterface: 
You are attempting to define `render` on your component more than once. 
This conflict may be due to a mixin.

displayName:你多次的对它进行设置是没有问题的,但是,最终的结果只以最后一次设置为准。

需要指出的是,mixin是可以包含在其他的mixin中的:

var UselessMixin = {
    componentDidMount: function () {
      console.log("asdas");
    }
};

var LolMixin = {
   mixins: [UselessMixin]
};

var PantsOpinion = React.createClass({
   mixins: [LolMixin],
   render: function () {
       return (

I dislike pants

); } }); React.renderComponent(, document.body);

程序会在控制台打印出asdas

包含多个 Mixins

我们的mixins要包裹在数组当中,提醒了我们可以在组件中包含多个mixins

var DefaultNameMixin = {
    getDefaultProps: function () {
        return {name: "Lizie"};
    }
};

var DefaultFoodMixin = {
    getDefaultProps: function () {
        return {food: "Pancakes"};
    }
};

var ComponentTwo = React.createClass({
    mixins: [DefaultNameMixin, DefaultFoodMixin],
    render: function () {
        return (
            

{this.props.name}

Favorite food: {this.props.food}

); } });
注意事项

这里有几件事需要引起我们的注意,当我们使用mixins的时候。 幸运地是,这些看起来并不是什么大问题,下面是我们在实践当中发现的一些问题:

设置相同的 Prop 和 State

如果你尝试在不同的地方定义相同的属性时会出现下面的异常:

Uncaught Error: Invariant Violation: mergeObjectsWithNoDuplicateKeys(): 
Tried to merge two objects with the same key: name
设置相同的方法

在不同的mixin中定义相同的方法,或者mixin和组件中包含了相同的方法时,会抛出异常:

var LogOnMountMixin = {
    componentDidMount: function () {
        console.log("mixin mount method");
        this.logBlah()
    },
    // add a logBlah method here...
    logBlah: function () {
        console.log("blah");
    }
};

var MoreLogOnMountMixin = {
    componentDidMount: function () {
        console.log("another mixin mount method");
    },
    // ... and again here.
    logBlah: function () {
        console.log("something other than blah");
    }
};

异常信息同多次定义rander方法时抛出的异常一样:

Uncaught Error: Invariant Violation: ReactCompositeComponentInterface: 
You are attempting to define `logBlah` on your component more than once. 
This conflict may be due to a mixin.
多个生命周期方法的调用顺序

如果我们的组件和mixin中都包含了相同的生命周期方法的话会怎样呢?

我们的mixin方法首先会被调用,然后再是组件的中方法被调用。

那当我们的组件中包含多个mixin,而这些mixin中又包含相同的生命周期方法时,调用顺序又是如何?

它们会根据mixins中的顺序从左到右的进行调用。

实例代码:

var LogOnMountMixin = {
    componentDidMount: function () {
        console.log("mixin mount method");
    }
};

var MoreLogOnMountMixin = {
    componentDidMount: function () {
        console.log("another mixin mount method");
    }
};
var ComponentOne = React.createClass({
    mixins: [MoreLogOnMountMixin, LogOnMountMixin],
    componentDidMount: function () {
        console.log("component one mount method");
    },
    ...

var ComponentTwo = React.createClass({
    mixins: [LogOnMountMixin, MoreLogOnMountMixin],
    componentDidMount: function () {
        console.log("component two mount method");
    },
    ...

控制台将输出:

another mixin mount method
mixin mount method 
component one mount method

mixin mount method
another mixin mount method 
component two mount method
总结

Mixin 使你React程序变得更为可重用,It"s a Good Thing.
我希望这篇文章能够对你有所帮助,如果有任何反馈,很高兴你能够在twitter上@veddermatic

原文链接:http://simblestudios.com/blog...

翻译水平有限,文中带有个人理解,如有不恰当的地方,请在评论中指出,非常感谢!

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/85837.html

相关文章

  • []Mixin 函数

    摘要:函数通常是面向对象编程风格,具有副作用。因为在函数式编程中,很有可能这些引用指向的并不是同一个对象。记住,函数并不意味着函数式编程。函数可以用函数式编程风格编写,避免副作用并不修改参数,但这并不保证。 软件构建系列 原文链接:Functional Mixins 译者注:在编程中,mixin 类似于一个固有名词,可以理解为混合或混入,通常不进行直译,本文也是同样。 这是软件构建系列教...

    zxhaaa 评论0 收藏0
  • []看这些文章,足够你学好redux

    摘要:原文地址我想分享一些文章,来帮你学习的概念和架构在开始之前我们先来看这两篇文章,用代替和然后我们通过一个代码教程我翻译地址深入了解,然后看一看超级介绍完成你对的探索之旅现在是时候去学习和再往前走理解并且看一看关于的一切注尽量中文地址的我用的 原文地址 我想分享一些文章,来帮你学习redux的概念和架构 在开始redux之前我们先来看这两篇文章,用High Order Component...

    fengxiuping 评论0 收藏0
  • React Mixin 前世今生

    摘要:但非常不幸,并不原生支持。这个单词相信都很熟悉,高阶函数在函数式编程是一个基本概念,它描述的是这样一种函数,接受函数作为输入,或是输出一个函数。比如常用的工具方法都是高阶函数。恰与的定义完全一致。这种不同很可能会导致问题的产生。 在 React component 构建过程中,常常有这样的场景,有一类功能要被不同的 Component 公用,然后看得到文档经常提到 Mixin(混入) ...

    姘存按 评论0 收藏0
  • 2017-06-15 前端日报

    摘要:前端日报精选十问帮你理清前端工程师及大前端团队的成长问题译读完细则之后学到的件事掘金怎么写一个组件库一众成翻译还有这操作一个能生成思维导图的开源搜索引擎知乎专栏中文前端推荐第天值得收藏的基础教程知乎专栏第期没有的一天转载中回调地 2017-06-15 前端日报 精选 十问sofish:帮你理清前端工程师及大前端团队的成长问题![译] 读完 flexbox 细则之后学到的 11 件事 -...

    Benedict Evans 评论0 收藏0
  • 学习 underscore 源码整体架构,打造属于自己函数式编程类库

    摘要:译立即执行函数表达式处理支持浏览器环境微信小程序。学习整体架构,利于打造属于自己的函数式编程类库。下一篇文章可能是学习的源码整体架构。也可以加微信,注明来源,拉您进前端视野交流群。 前言 上一篇文章写了jQuery整体架构,学习 jQuery 源码整体架构,打造属于自己的 js 类库 虽然看过挺多underscore.js分析类的文章,但总感觉少点什么。这也许就是纸上得来终觉浅,绝知此...

    junnplus 评论0 收藏0

发表评论

0条评论

张巨伟

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<