转载来源 感谢分享

Mixins 引入了无形的依赖

  • 应尽量构建无状态组件,Mixin 则反其道而行之
  • Mixin 可能会相互依赖,相互耦合,不利于代码维护
  • 不同的 Mixin 中的方法可能会相互冲突

举个例子

Mixins 有个主要用途是组件从其它数据源订阅数据:

class CommentList extends React.Component {
this.state = {
// "DataSource" 就是全局的数据源
comments: DataSource.getComments()
} componentDidMount() {
// 添加事件处理函数订阅数据
DataSource.addChangeListener(this.handleChange);
} componentWillUnmount() {
// 清除事件处理函数
DataSource.removeChangeListener(this.handleChange);
} handleChange = () => {
// 任何时候数据发生改变就更新组件
this.setState({
comments: DataSource.getComments()
})
} render() {
return (
<div>
{this.state.comments.map((comment) => (
<Comment comment={comment} key={comment.id} />
))}
</div>
)
}
}

当多个组件共用此逻辑时,使用 高阶组件 来优化:

const CommentListWithSubscription = withSubscription(
CommentList,
(DataSource) => DataSource.getComments()
) const BlogPostWithSubscription = withSubscription(
BlogPost,
(DataSource, props) => DataSource.getBlogPost(props.id)
) // 函数接受一个组件参数……
function withSubscription(WrappedComponent, selectData) {
// ……返回另一个新组件……
return class extends React.Component {
this.state = {
data: selectData(DataSource, props)
} componentDidMount() {
// ……注意订阅数据……
DataSource.addChangeListener(this.handleChange)
} componentWillUnmount() {
DataSource.removeChangeListener(this.handleChange)
} handleChange = () => {
this.setState({
data: selectData(DataSource, this.props)
})
} render() {
// ……使用最新的数据渲染组件
// 注意此处将已有的props属性传递给原组件
return <WrappedComponent data={this.state.data} {...this.props} />
}
}
}

高阶组件既不会修改 input 原组件,也不会使用继承复制 input 原组件的行为。相反,高阶组件是通过将原组件包裹(wrapping)在容器组件(container component)里面的方式来组合(composes)使用原组件。高阶组件就是一个没有副作用的纯函数。

抽取状态

说白了就是在无状态组件和其容器组件的关系中,通常让无状态组件不管理自己的状态,状态的管理交给外面的容器组件。

react-redux 的 connect 函数就用来抽取状态,它返回一个高阶组件。

假定你了解 Redux,那么可以看下 connect 的简易实现:

const doNothing = () => ({})

function connect(mapStateToProps=doNothing, mapDispatchToProps=doNothing) {
return function(WarppedComponent) {
class HOC extends React.Component {
this.state = {} componentDidMount() {
this.context.store.subscribe(this.onChange)
} componentWillUmount() {
this.context.store.unsubscribe(this.onChange)
} // HOC 保证 Redux 上 Store 状态变化的时候驱动这个组件的更新
onChange = () => this.setState({}) render() {
const store = this.centext.store
// 执行 getState 得到 Redux Store 状态
// 通过 dispatch 得到传递给 mapDispatchToProps 的 dispatch 方法
const newProps = {
...this.props,
...mapStateToProps(store.getState()),
...mapDispatchToProps(store.dispatch)
} return <WarppedComponent {...newProps} />
}
} // 创建新组件需要利用 Context 功能,所以定义了 types 属性,
// 从 Context 中获取名为 store 的值
HOC.contextTypes = { store.React.PropTypes.object } return HOC
}
}

浅析为什么用高阶组件代替 Mixins的更多相关文章

  1. Mixins 改成使用高阶组件调用

    把组件放在另外一个组件的 render 方法里面, 并且利用了 {...this.props} {...this.state} 这些  JSX 展开属性 对比下2种代码: 原始方式: <!DOC ...

  2. React 高阶组件浅析

    高阶组件的这种写法的诞生来自于社区的实践,目的是解决一些交叉问题(Cross-Cutting Concerns).而最早时候 React 官方给出的解决方案是使用 mixin .而 React 也在官 ...

  3. React文档(二十四)高阶组件

    高阶组件(HOC)是React里的高级技术为了应对重用组件的逻辑.HOCs本质上不是React API的一部分.它是从React的组合性质中显露出来的模式. 具体来说,一个高阶组件就是一个获取一个组件 ...

  4. React高阶组件总结

    在多个不同的组件中需要用到相同的功能,这个解决方法,通常有Mixin和高阶组件. Mixin方法例如: //给所有组件添加一个name属性 var defaultMixin = { getDefaul ...

  5. vue-mixins和vue高阶组件

    我们在开发过程中,因为需求的变更,往往会遇见对现有组件的改造和扩展. 那么我们有什么方法对现有组件进行改造和扩展呢? 常见的我们可以使用mixins方式 下面就让我们来看一下怎么使用mixins方式对 ...

  6. 聊聊React高阶组件(Higher-Order Components)

    使用 react已经有不短的时间了,最近看到关于 react高阶组件的一篇文章,看了之后顿时眼前一亮,对于我这种还在新手村晃荡.一切朝着打怪升级看齐的小喽啰来说,像这种难度不是太高同时门槛也不是那么低 ...

  7. React——高阶组件

    1.在React中higher-order component (HOC)是一种重用组件逻辑的高级技术.HOC不是React API中的一部分.HOC是一个函数,该函数接收一个组件并且返回一个新组件. ...

  8. react 高阶组件的 理解和应用

    高阶组件是什么东西 简单的理解是:一个包装了另一个基础组件的组件.(相对高阶组件来说,我习惯把被包装的组件称为基础组件) 注意:这里说的是包装,可以理解成包裹和组装: 具体的是高阶组件的两种形式吧: ...

  9. React 精要面试题讲解(五) 高阶组件真解

    说明与目录 在学习本章内容之前,最好是具备react中'插槽(children)'及'组合与继承' 这两点的知识积累. 详情请参照React 精要面试题讲解(四) 组合与继承不得不说的秘密. 哦不好意 ...

随机推荐

  1. wpf 虚拟键盘 对外部程序

    对外部程序,以记事本为例,xaml中设置模拟按键的控件 Focusable="False": /// <summary> /// 发送按键 /// </summa ...

  2. kendo Ui实现搜索选中建议 不改变输入框的值

    $("#SubjectFilter").kendoAutoComplete({ dataTextField: "patientCardNumber", temp ...

  3. oracle group by rollup实现小计、合计

    SQL合计汇总实现数据N+1条显示: 注意group by rollup((ename, job, empno))!!! select decode(grouping(ename) + groupin ...

  4. JDBC的一些简单通用代码

    JDBC的一些简单通用代码 功能包括 连接数据库 查询操作 执行sql语句 jdbc相关类的加载 关闭连接 获取数据库格式的当前时间 代码 package dao; import java.sql.C ...

  5. eclipse 逆向生成hbm配置文件及pojo

    1.eclipse配置hibernate环境 由于在公司中不能在线安装jboss Tools,只能简单介绍手动安装 在jboss官网下载对应自己eclipse的压缩包. 在eclipse 中选择Hel ...

  6. nginx配置本地域名反向代理实现本地多域名80访问

    什么是反向代理? 代理:通过客户机的配置,实现让一台服务器代理客户机,客户的所有请求都交给代理服务器处理. 反向代理:用一台服务器,代理真实服务器,用户访问时,不再是访问真实服务器,而是代理服务器. ...

  7. springboot2.0国际化

    springboot2.0配合thymeleaf实现页面国际化 1. 引入thymeleaf <?xml version="1.0" encoding="UTF-8 ...

  8. redis 字符串 数据类型

    1 字符串 设置:   set    key  value   获取:  get  key    删除:  del   key getrange   key    0 3    截取字符串内容    ...

  9. win10 powershell禁止运行脚本解决

    win10 现在默认策略为 Restricted 该策略情况下是禁止在终端下运行脚本文件的,所以我们想要通过powershell 来运行我们的脚本文件的话就需要我们更改其策略才行,如下命令可以帮助你 ...

  10. jenkins配置windows节点遇到的问题

    配置:https://blog.csdn.net/liuchunming033/article/details/52025541 错误: 使用slave-agent.jnlp启动时报以下错误,是mas ...