浅析为什么用高阶组件代替 Mixins
转载来源 感谢分享
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的更多相关文章
- Mixins 改成使用高阶组件调用
把组件放在另外一个组件的 render 方法里面, 并且利用了 {...this.props} {...this.state} 这些 JSX 展开属性 对比下2种代码: 原始方式: <!DOC ...
- React 高阶组件浅析
高阶组件的这种写法的诞生来自于社区的实践,目的是解决一些交叉问题(Cross-Cutting Concerns).而最早时候 React 官方给出的解决方案是使用 mixin .而 React 也在官 ...
- React文档(二十四)高阶组件
高阶组件(HOC)是React里的高级技术为了应对重用组件的逻辑.HOCs本质上不是React API的一部分.它是从React的组合性质中显露出来的模式. 具体来说,一个高阶组件就是一个获取一个组件 ...
- React高阶组件总结
在多个不同的组件中需要用到相同的功能,这个解决方法,通常有Mixin和高阶组件. Mixin方法例如: //给所有组件添加一个name属性 var defaultMixin = { getDefaul ...
- vue-mixins和vue高阶组件
我们在开发过程中,因为需求的变更,往往会遇见对现有组件的改造和扩展. 那么我们有什么方法对现有组件进行改造和扩展呢? 常见的我们可以使用mixins方式 下面就让我们来看一下怎么使用mixins方式对 ...
- 聊聊React高阶组件(Higher-Order Components)
使用 react已经有不短的时间了,最近看到关于 react高阶组件的一篇文章,看了之后顿时眼前一亮,对于我这种还在新手村晃荡.一切朝着打怪升级看齐的小喽啰来说,像这种难度不是太高同时门槛也不是那么低 ...
- React——高阶组件
1.在React中higher-order component (HOC)是一种重用组件逻辑的高级技术.HOC不是React API中的一部分.HOC是一个函数,该函数接收一个组件并且返回一个新组件. ...
- react 高阶组件的 理解和应用
高阶组件是什么东西 简单的理解是:一个包装了另一个基础组件的组件.(相对高阶组件来说,我习惯把被包装的组件称为基础组件) 注意:这里说的是包装,可以理解成包裹和组装: 具体的是高阶组件的两种形式吧: ...
- React 精要面试题讲解(五) 高阶组件真解
说明与目录 在学习本章内容之前,最好是具备react中'插槽(children)'及'组合与继承' 这两点的知识积累. 详情请参照React 精要面试题讲解(四) 组合与继承不得不说的秘密. 哦不好意 ...
随机推荐
- 40组合总和II
题目:给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合.candidates 中的每个数字在每个组合中只能使用一 ...
- 一张图包含SEO一切要点
看到一张好图 from http://www.rongyipiao.com/?p=8
- unity shader 波动圈
c# //////////////////////////////////////////// // CameraFilterPack - by VETASOFT 2018 ///// /////// ...
- [转帖]Linux网络管理员不得不了解的系统目录/proc/sys/net/(网络配置)
Linux网络管理员不得不了解的系统目录/proc/sys/net/(网络配置) https://blog.csdn.net/u013485792/article/details/76416836 需 ...
- (5.2)mysql高可用系列——测试环境部署
关键词环境部署: ############## 测试环境机器架构 #########[1]策划[1.1]linux服务器A组 8台 192.168.1.200~192.168.1.207,主机名db, ...
- QT use of undeclared identifier 'cout'
在QT 5.12中直接使用cout将提示错误如下: 添加库 #include<iostream>,并将cout&end改为std::cout&std::endl 代码如下: ...
- python根据文本生成词云图
python根据文本生成词云图 效果 代码 from wordcloud import WordCloud import codecs import jieba #import jieba.analy ...
- Android快捷键大全
参考来源:https://mp.weixin.qq.com/s/T809p17Wt8XHkbLwcQf9ow 1,Ctrl + J 快捷代码列表 2,Ctrl+Alt+O 这个快捷键可以自动导包或删 ...
- python__基础数据类型
字符串和常用数据结构 使用字符串 第二次世界大战促使了现代电子计算机的诞生,当初的想法很简单,就是用计算机来计算导弹的弹道,因此在计算机刚刚诞生的那个年代,计算机处理的信息主要是数值,而世界上的第一台 ...
- [LeetCode] 完全二叉树的节点个数
题目链接: https://leetcode-cn.com/problems/count-complete-tree-nodes 难度:中等 通过率:57.4% 题目描述: 给出一个 完全二叉树 ,求 ...