学习react系列(八)—— mixins迁移
先来介绍一下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迁移的更多相关文章
- 学习React系列(十)——Render Props
解决问题:将行为封装,供多个组件使用(在多个组件之间分享某段代码) 组件中的props属性中包含一个"render"属性(该属性为一个返回值为元素的方法),然后在该组件的rende ...
- 学习React系列(九)——高阶函数
定义:高阶组件就是一个函数,且该函数接收一个组件作为参数,并返回一个新的组件. (上一篇已经说过了高阶组件可以用来解决交叉问题) 一.不要改变原始组件,使用组合 class A extends Rea ...
- 学习React系列(七)——Fragments、Portals、Error Boundaries与WEB组件
React.Fragment portals Error Boundaries WEB组件 React.Fragment 想象一个场景,想把td包装为组件添加到table中去,代码如下: class ...
- 学习React系列(六)——更新dom细节于原理
React更新dom的依据: 1.不同类型的elements会产生不同的树 2.通过render方法中包含key属性的子元素,开发者可以示意哪些子元素可能是稳定的. 更新过程: 一.根元素类型不同:旧 ...
- 学习React系列(五)——使性能最优
提高性能可分为两方面: 一.配置层面 二.代码层面 本文只从代码层面考虑: 一.避免重复渲染 这里要说一句: 当shouldComponentUpdate返回false的时候不触发render函数也就 ...
- 学习React系列(四)——受控组件与非受控组件
受控组件:通过组件的状态与属性的改变来控制组件 不可控组件:直接通过底层的dom来控制组件(具体来说就是通过绑定再底层dom上的方法来实现的,比如说ref,onChange) 受控组件 functio ...
- 学习React系列(三)——Refs和Dom
一.适用于以下场景: 1.控制焦点,文本选择,或者媒体控制 2.触发必要的动画 3.整合第三方dom库 二.不要过度使用ref 如果想通过ref来改变state,那么换一种方式-变量提升可能会更好. ...
- 学习React系列(二)——深入了解JSX
1.JX实际上是React.createElement(component,props,...children)的语法糖 2.JSX判断是否为react组件的依据是标签首字母为大写(所以要求用户自定义 ...
- 学习React系列(一)——React.Component 生命周期
挂载中(只执行一次) 以下方法在组件实例正被创建和插入到DOM中时调用 constructor()一般用于初始化state和方法的this绑定 componentWillMount() render( ...
随机推荐
- Java高级篇(一)——线程
前面我们系统的了解了Java的基础知识,本篇开始将进入到Java更深层次的介绍,我们先来介绍一下Java中的一个重要的概念--线程. 一.什么是线程 在了解线程前,我们首先要了解进程的概念.进程是操作 ...
- 【Python】 xml转json
虽然python有解析xml的模块,也有生成json的模块,但是没有把这两者连接起来的模块. 下面是以来自MIT的大神Martin Blech写的一个方便的模块,供大家参考.也别忘了在用之前先拜谢作者 ...
- Java NIO系列教程(六) 多路复用器Selector
多路复用器Selector是Java NIO编程的基础,熟练地掌握Selector对于掌握NIO编程至关重要.多路复用器提供选择已经就绪的任务的能力.简单来讲,Selector会不断地轮询注册在其上的 ...
- Oracle查询优化改写--------------------单表查询
一.查询表中所有的行与列 二.从表中检索部分行 三.查找空值 四.将空值转化为实际值(coalesce) 五.查找满足多个条件的行(查询部门为10中所有的员工.所有得到提成的员工,以及部门20中工资不 ...
- java并发编程基础 --- 7章节 java中的13个原子操作类
当程序更新一个变量时,如果多线程同时更新这个变量,可能得到期望之外的值,比如变量 i=1,A线程更新 i+1,B线程也更新 I+1,经过两个线程的操作之后可能 I不等于3,而是等于2.因为A和B线程更 ...
- Axure RP初学
制作商品购买页
- (译文)学习ES6非常棒的特性-字符串常量基础
字符串常量基础 在ES2015之前我们是这么拼接字符串的: var result = 10; var prefix = "the first double digit number I le ...
- C语言程序设计课程总结
第一次教授C语言程序设计课程,相比计算机组成原理.arm体系结构等偏向硬件的课程,C的教学方式要灵活一些.计算机组成原理课程偏向理论,哈尔滨工业大学的计算机组成原理是国家精品课,增加了mooc+spo ...
- 2017-2018-1 20155306 《信息安全系统设计基础》Mybash的实现
2017-2018-1 20155306 <信息安全系统设计基础>Mybash的实现 要求: 使用fork,exec,wait实现mybash 写出伪代码,产品代码和测试代码 发表知识理解 ...
- Flask 扩展 国际化 本地化
pip install flask-babel 先初始化一个Flask-Babel的实例 from flask import Flask from flask.ext.babel import Bab ...