关于今天要学习的组件间抽象其实我这小白看了几次还没弄明白, 这次决定一探究竟. 在组件构建中, 通常有一类功能需要被不同的组件公用, 此时就涉及抽象的概念, 在 React 中我们主要了解 mixin 和高阶组件.
mixin
mixin 的特性广泛存在于各个面向对象语言中, 在 ruby 中, include 关键词就是 mixin, 是将一个模块混入到另外一个模块中, 或者是类中.
封装 mixin 方法
const mixin = function(obj, mixins) {
const newObj = obj
newObj.prototype = Object.create(obj.prototype)
for(let props in mixins) {
newObj.prototype[props] = mixins[props]
}
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()
FlyBig.fly() //'i can fly'
对于广义的 mixin 方法, 就是用赋值的方式将 mixin 对象里的方法都挂载到原对象上去, 来实现对对象的混入.
React 中的 mixin
React 在使用 createClass 构建组件时提供了 mixin 属性, 如官方的 PureRenderMixin:
import React from 'react'
import PureRenderMixin from 'react-addons-pure-render-mixin'
React.createClass({
mixins: [PureRenderMixin]
render() {
return <div>foo</foo>
}
})
在 createClass 对象参数中传入数组 mixins, 里面封装了我们所需要的模块, mixins 数组也可以增加多个 mixin, 其每一个 mixin 方法之间的有重合, 对于普通方法和生命周期方法是有所区分的.
在不同的 mixin 里实现两个名字一样的普通方法, 在 React 中是不会被覆盖的, 会在控制台中报一个 ReactClassInterface 里的错误, 指出你尝试在组件中多次定义一个方法.** 因此在 React 中是不允许出现崇明普通方法的 mixins, 如果是 React 生命周期定义的方法, 则会将各个模块的生命周期方法叠加在一起顺序执行 **.
我们看到使用 createClass 的 mixin 为组价做了两件事情:
1. 工具方法: 为组件共享了一些工具类方法, 可以在各个组件中使用.
2. 生命周期继承: props 和 state 合并, mixin 能够合并生命周期方法, 如果有很多 mixin 来定义 componentDidMount 这个周期,
那么 React 会非常智能的将他们合并一起执行.
ES6 CLASS 和 decorator
现在我们比较推崇使用 es6 class 方法去构建组件, 但是它并不支持 mixin. 官方文档中也没有给出很好的办法.
decorator 是 ES 7 中定义的特性, 和 Java 中的注解相似. decorator 是运用在运行时的方法, 在 redux 或者其他应用层框架中, 越来越多的使用 decorator 实现对组件的装饰.
core-decorator 库为开发者提供了一些实用的 decorator, 其中实现了我们正想要的 @mixin. 它将每个 mixin 对象的方法都叠加到 target 对象的原型上以达到 mixin 的目的.
import React, { Component } from 'react'
import { mixin } from 'core-decorator'
const PuerRender = {
setTheme()
}
const Them = {
setTheme()
}
@mixin(PuerRender, Them)
class MyComponent extends Component {
render() {...}
}
如上 decorator 只是作用在类上面的, 还有作用在方法上面的, 它可以控制方法的自有属性.
注意: react 0.14 开始剥离 mixin
mixin 的问题
破坏了原有组件的封装
mixin 方法可以混入方法给组件带来新的特性, 也会带来新的 props 和 state, 这意味着有些不可见的状态需要我们去维护. mixin 也有可能存在相互依赖, 这样形式依赖链, 相互之间会影响.
命名冲突
增加复杂性
来源: http://www.jb51.net/article/133817.htm