先来介绍一下mixins(混入)

先来看一段代码:

const mixin = function(obj, mixins) {
const newObj = obj;
newObj.prototype = Object.create(obj.prototype); for (let prop in mixins) {
if (mixins.hasOwnProperty(prop)) {
newObj.prototype[prop] = mixins[prop];
}
} return newObj;
} const BigMixin = {
fly: () => {
console.log('I can fly');
}
}; const Big = function() {
console.log('new big');
}; const FlyBig = mixin(Big, BigMixin); const flyBig = new FlyBig(); // 'new big'
flyBig.fly(); // 'I can fly'

对于广义的 mixin 方法,就是用赋值的方式将 mixins 对象里的方法都挂载到原对象上,就实现了对对象的混入

在来看看React中的使用方式:

import React from 'react';
import PureRenderMixin from 'react-addons-pure-render-mixin'; React.createClass({
mixins: [PureRenderMixin], render() {
return <div>foo</div>;
}
});

React中的mixins其实就是将一段公共代码提供过React组件使用,减少代码的复用。

现在来说说mixins的弊端:

一、mixins隐含依赖

二、造成命名冲突

三、实际上它可能会越滚越大影响了初衷

由于以上弊端,将mixins进行迁移显的尤为重要

一、最优渲染

var PureRenderMixin = require('react-addons-pure-render-mixin');

var Button = React.createClass({
mixins: [PureRenderMixin], // ... }); 现在使用React.PureComponent

二、重用属性(以下代码都为简写)

var SubscriptionMixin = {
componentDidMount: function() {
DataSource.addChangeListener(this.handleChange);
},
}; var CommentList = React.createClass({
mixins: [SubscriptionMixin], render: function() {
}
}); 现在使用高阶组件,将组件分成子组件与父组件,子组件关注与渲染逻辑,父组件用来建立重用属性,并使用状态自上到下通过props传递给子组件,最后将父组件转变为一可以传入子组件的函数,大功告成。
function withSubscription(WrappedComponent) {
return React.createClass({
getInitialState: function() {
return {
comments: DataSource.getComments()
};
}, componentDidMount: function() {
DataSource.addChangeListener(this.handleChange);
},
render: function() {
// Use JSX spread syntax to pass all props and state down automatically.
return <WrappedComponent {...this.props} {...this.state} />;
}
});
} // Optional change: convert CommentList to a functional component
// because it doesn't use lifecycle hooks or state.
function CommentList(props) {
var comments = props.comments;
return (
<div>
{comments.map(function(comment) {
return <Comment comment={comment} key={comment.id} />
})}
</div>
)
}
module.exports = withSubscription(CommentList);
 

三、渲染逻辑

多个组件需要相同的渲染逻辑,以前的处理方式是

var RowMixin = {
renderHeader: function() {
return (
...
);
}
}; var UserRow = React.createClass({
mixins: [RowMixin],
getHeaderText: function() {
return this.props.user.fullName;
},
render: function() {
return (
<div>
{this.renderHeader()}
</div>
)
}
}); 现在提倡直接额外新建立一个组件,使用的时候引入就好了

四、上下文

这里提倡通过高阶组件来实现

五、方法工具

以前是将所有方法写到对象中,然后将对象添加到mixins中

现在提倡将所有的方法放到js模块中,然后通过导入该模块,进而调用。

结论:其实通过以上的例子,可以看出,通过createClass的方式创建的组件,将一个对象放入到mixins之后,该组件就继承了对象的所有属性,进而可以直接通过this调用。

参考:https://reactjs.org/blog/2016/07/13/mixins-considered-harmful.html

学习react系列(八)—— mixins迁移的更多相关文章

  1. 学习React系列(十)——Render Props

    解决问题:将行为封装,供多个组件使用(在多个组件之间分享某段代码) 组件中的props属性中包含一个"render"属性(该属性为一个返回值为元素的方法),然后在该组件的rende ...

  2. 学习React系列(九)——高阶函数

    定义:高阶组件就是一个函数,且该函数接收一个组件作为参数,并返回一个新的组件. (上一篇已经说过了高阶组件可以用来解决交叉问题) 一.不要改变原始组件,使用组合 class A extends Rea ...

  3. 学习React系列(七)——Fragments、Portals、Error Boundaries与WEB组件

    React.Fragment portals Error Boundaries WEB组件 React.Fragment 想象一个场景,想把td包装为组件添加到table中去,代码如下: class ...

  4. 学习React系列(六)——更新dom细节于原理

    React更新dom的依据: 1.不同类型的elements会产生不同的树 2.通过render方法中包含key属性的子元素,开发者可以示意哪些子元素可能是稳定的. 更新过程: 一.根元素类型不同:旧 ...

  5. 学习React系列(五)——使性能最优

    提高性能可分为两方面: 一.配置层面 二.代码层面 本文只从代码层面考虑: 一.避免重复渲染 这里要说一句: 当shouldComponentUpdate返回false的时候不触发render函数也就 ...

  6. 学习React系列(四)——受控组件与非受控组件

    受控组件:通过组件的状态与属性的改变来控制组件 不可控组件:直接通过底层的dom来控制组件(具体来说就是通过绑定再底层dom上的方法来实现的,比如说ref,onChange) 受控组件 functio ...

  7. 学习React系列(三)——Refs和Dom

    一.适用于以下场景: 1.控制焦点,文本选择,或者媒体控制 2.触发必要的动画 3.整合第三方dom库 二.不要过度使用ref 如果想通过ref来改变state,那么换一种方式-变量提升可能会更好. ...

  8. 学习React系列(二)——深入了解JSX

    1.JX实际上是React.createElement(component,props,...children)的语法糖 2.JSX判断是否为react组件的依据是标签首字母为大写(所以要求用户自定义 ...

  9. 学习React系列(一)——React.Component 生命周期

    挂载中(只执行一次) 以下方法在组件实例正被创建和插入到DOM中时调用 constructor()一般用于初始化state和方法的this绑定 componentWillMount() render( ...

随机推荐

  1. Java高级篇(一)——线程

    前面我们系统的了解了Java的基础知识,本篇开始将进入到Java更深层次的介绍,我们先来介绍一下Java中的一个重要的概念--线程. 一.什么是线程 在了解线程前,我们首先要了解进程的概念.进程是操作 ...

  2. 【Python】 xml转json

    虽然python有解析xml的模块,也有生成json的模块,但是没有把这两者连接起来的模块. 下面是以来自MIT的大神Martin Blech写的一个方便的模块,供大家参考.也别忘了在用之前先拜谢作者 ...

  3. Java NIO系列教程(六) 多路复用器Selector

    多路复用器Selector是Java NIO编程的基础,熟练地掌握Selector对于掌握NIO编程至关重要.多路复用器提供选择已经就绪的任务的能力.简单来讲,Selector会不断地轮询注册在其上的 ...

  4. Oracle查询优化改写--------------------单表查询

    一.查询表中所有的行与列 二.从表中检索部分行 三.查找空值 四.将空值转化为实际值(coalesce) 五.查找满足多个条件的行(查询部门为10中所有的员工.所有得到提成的员工,以及部门20中工资不 ...

  5. java并发编程基础 --- 7章节 java中的13个原子操作类

    当程序更新一个变量时,如果多线程同时更新这个变量,可能得到期望之外的值,比如变量 i=1,A线程更新 i+1,B线程也更新 I+1,经过两个线程的操作之后可能 I不等于3,而是等于2.因为A和B线程更 ...

  6. Axure RP初学

    制作商品购买页

  7. (译文)学习ES6非常棒的特性-字符串常量基础

    字符串常量基础 在ES2015之前我们是这么拼接字符串的: var result = 10; var prefix = "the first double digit number I le ...

  8. C语言程序设计课程总结

    第一次教授C语言程序设计课程,相比计算机组成原理.arm体系结构等偏向硬件的课程,C的教学方式要灵活一些.计算机组成原理课程偏向理论,哈尔滨工业大学的计算机组成原理是国家精品课,增加了mooc+spo ...

  9. 2017-2018-1 20155306 《信息安全系统设计基础》Mybash的实现

    2017-2018-1 20155306 <信息安全系统设计基础>Mybash的实现 要求: 使用fork,exec,wait实现mybash 写出伪代码,产品代码和测试代码 发表知识理解 ...

  10. Flask 扩展 国际化 本地化

    pip install flask-babel 先初始化一个Flask-Babel的实例 from flask import Flask from flask.ext.babel import Bab ...