为什么使用 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 <h2>Hello {this.props.name}</h2>;
}
}); React.renderComponent(<ComponentOne />, document.body);

重复使用

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

var ComponentTwo = React.createClass({
mixins: [DefaultNameMixin],
render: function () {
return (
<div>
<h4>{this.props.name}</h4>
<p>Favorite food: {this.props.food}</p>
</div>
);
}
});

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

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

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

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

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

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

var UselessMixin = {
componentDidMount: function () {
console.log("asdas");
}
}; var LolMixin = {
mixins: [UselessMixin]
}; var PantsOpinion = React.createClass({
mixins: [LolMixin],
render: function () {
return (<p>I dislike pants</p>);
}
}); React.renderComponent(<PantsOpinion />, 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 (
<div>
<h4>{this.props.name}</h4>
<p>Favorite food: {this.props.food}</p>
</div>
);
}
});

注意事项

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

设置相同的 Prop 和 State

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

设置相同的方法

在不同的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方法时抛出的异常一样:

多个生命周期方法的调用顺序

如果我们的组件和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.

React Mixin的更多相关文章

  1. React.js 常用技术要点

    最近在公司的一个移动端WEB产品中使用了React这个框架(并不是React-Native),记录一下在开发过程中遇到的各种问题以及对应的解决方法,希望能对读者有所帮助. React原则 React不 ...

  2. React-代码复用(mixin.hoc.render props)

    前言 最近在学习React的封装,虽然日常的开发中也有用到HOC或者Render Props,但从继承到组合,静态构建到动态渲染,都是似懂非懂,索性花时间系统性的整理,如有错误,请轻喷~~ 例子 以下 ...

  3. react创建组件的几种方式及其区别

    react创建组件有如下几种方式 ①.函数式定义的无状态组件 ②.es5原生方式React.createClass定义的组件   ③.es6形式的extends React.Component定义的组 ...

  4. React创建组件的三种方式及其区别

    内容转载于http://www.cnblogs.com/wonyun/p/5930333.html React推出后,出于不同的原因先后出现三种定义react组件的方式,殊途同归; 具体的三种方式: ...

  5. 使用react常见的坑

    触摸事件 React中的触摸事件仅用三种,touchstart, touchend, touchend,可是这种会有问题,有时候我需要滚动页面的时候,很容易触发某一个元素的touchend事件,为此笔 ...

  6. 【03】react 之 创建component

    React推出后,出于不同的原因先后出现三种定义react组件的方式,殊途同归:具体的三种方式: 函数式定义的无状态组件 es5原生方式React.createClass定义的组件 es6形式的ext ...

  7. React 代码共享最佳实践方式

    任何一个项目发展到一定复杂性的时候,必然会面临逻辑复用的问题.在React中实现逻辑复用通常有以下几种方式:Mixin.高阶组件(HOC).修饰器(decorator).Render Props.Ho ...

  8. react-native-android之初次相识

    作为一名Android开发者,我的感觉就是,一步一卡,卡的潇洒. 但是我还是要学react-native,不要问我为什么,因为我相信一门解决了原生app,开发周期长,开发成本高,升级代价大的语言一定会 ...

  9. 301-React Ext-React创建组件的三种方式及其区别

    一.概述 React推出后,出于不同的原因先后出现三种定义react组件的方式,殊途同归:具体的三种方式: 函数式定义的无状态组件 es5原生方式React.createClass定义的组件 es6形 ...

随机推荐

  1. 【模板】DFS

    int dx[] = { 0,1,0,-1 }; int dy[] = { 1,0,-1,0 }; void dfs()//参数用来表示状态 { if (到达终点状态) { ...//根据题意来添加 ...

  2. 【Machine Learning】如何处理机器学习中的非均衡数据集?

    在机器学习中,我们常常会遇到不均衡的数据集.比如癌症数据集中,癌症样本的数量可能远少于非癌症样本的数量:在银行的信用数据集中,按期还款的客户数量可能远大于违约客户的样本数量.   比如非常有名的德国信 ...

  3. LeetCode - 326, 342, 231 Power of Three, Four, and Two

    1. 问题 231. Power of Two: 判断一个整数是否是2的n次方,其中n是非负整数 342. Power of Four: 判断一个整数是否是4的n次方,其中n是非负整数 326. Po ...

  4. Juice账号

    zhangxiaocong69 zxc6545398 15657167502 区块链账户: 0x00680404766965143796a0a070835c3cdf9a4a50

  5. 基于freeRTOS定时器实现闹钟(定时)任务

    基于freeRTOS定时器实现闹钟(定时)任务 在智能硬件产品中硬件中,闹钟定时任务是基本的需求.一般通过APP设置定时任务,从云端或者是APP直连硬件将闹钟任务保存在硬件flash中,硬件运行时会去 ...

  6. node.js应用--转载

    最近,在向大学生们介绍 HTML5 的时候,我想要对他们进行问卷调查,并向他们显示实时更新的投票结果.鉴于此目的,我决定快速构建一个用于此目的的问卷调查应用程序.我想要一个简单的架构,不需要太多不同的 ...

  7. Ubuntu16.0.4 安装mysql

    1. sudo apt-get install mysql-server 2. sudo apt-get install mysql-client 3.  sudo apt-get install l ...

  8. ACM 第六天

    图论 网络流 最大流 INF(初始值) 路径上权值最小的边,决定流量大小. 流量网络的三个特性: ①流量控制 ②反对称性 ③流量守恒 残余网络:保留了c(e)容量<f(e)流量[可以继续流,因为 ...

  9. LintCode-5.第k大元素

    第k大元素 在数组中找到第k大的元素 注意事项 你可以交换数组中的元素的位置 样例 给出数组 [9,3,2,4,8],第三大的元素是 4 给出数组 [1,2,3,4,5],第一大的元素是 5,第二大的 ...

  10. LintCode-73.前序遍历和中序遍历树构造二叉树

    前序遍历和中序遍历树构造二叉树 根据前序遍历和中序遍历树构造二叉树. 注意事项 你可以假设树中不存在相同数值的节点 样例 给出中序遍历:[1,2,3]和前序遍历:[2,1,3]. 返回如下的树:    ...