React 高阶组件入门介绍


Posted in Javascript onJanuary 11, 2018

高阶组件的定义

HoC 不属于 React 的 API,它是一种实现模式,本质上是一个函数,接受一个或多个 React 组件作为参数,返回一个全新的 React 组件,而不是改造现有的组件,这样的组件被称为高阶组件。开发过程中,有的功能需要在多个组件类复用时,这时可以创建一个 Hoc。

基本用法

包裹方式

const HoC = (WrappendComponent) => {
 const WrappingComponent = (props) => (
  <div className="container">
   <WrappendComponent {...props} />
  </div>
 );
 return WrappingComponent;
};

上述代码中,接受 WrappendComponent 作为参数,此参数就是将要被 HoC 包装的普通组件,在 render 中包裹一个 div,赋予它 className 属性,最终产生的 WrappingComponent 和 传入的 WrappendComponent 是两个完全不同的组件。

在 WrappingComponent 中,可以读取、添加、编辑、删除传给 WrappendComponent 的 props,也可以用其它元素包裹 WrappendComponent,用来实现封装样式、添加布局或其它操作。

组合方式

const HoC = (WrappedComponent, LoginView) => {
 const WrappingComponent = () => {
  const {user} = this.props; 
  if (user) {
   return <WrappedComponent {...this.props} />
  } else {
   return <LoginView {...this.props} />
  }
 };
 return WrappingComponent;
};

上述代码中有两个组件,WrappedComponent 和 LoginView,如果传入的 props 中存在 user,则正常显示的 WrappedComponent 组件,否则显示 LoginView 组件,让用户去登录。HoC 传递的参数可以为多个,传递多个组件定制新组件的行为,例如用户登录状态下显示主页面,未登录显示登录界面;在渲染列表时,传入 List 和 Loading 组件,为新组件添加加载中的行为。

继承方式

const HoC = (WrappendComponent) => {
 class WrappingComponent extends WrappendComponent {
  render() (
   const {user, ...otherProps} = this.props;
   this.props = otherProps;
   return super.render();
  }
 }
 return WrappingComponent;
};

WrappingComponent 是一个新组件,它继承自 WrappendComponent,共享父级的函数和属性。可以使用 super.render() 或者 super.componentWillUpdate() 调用父级的生命周期函数,但是这样会让两个组件耦合在一起,降低组件的复用性。

React 中对组件的封装是按照最小可用单元的思想来进行封装的,理想情况下,一个组件只做一件事情,符合 OOP 中的单一职责原则。如果需要对组件的功能增强,通过组合的方式或者添加代码的方式对组件进行增强,而不是修改原有的代码。

注意事项

不要在 render 函数中使用高阶组件

render() {
 // 每一次render函数调用都会创建一个新的EnhancedComponent实例
 // EnhancedComponent1 !== EnhancedComponent2
 const EnhancedComponent = enhance(MyComponent);
 // 每一次都会使子对象树完全被卸载或移除
 return <EnhancedComponent />;
}

React 中的 diff 算法会比较新旧子对象树,确定是否更新现有的子对象树或丢掉现有的子树并重新挂载。

必须将静态方法做拷贝

// 定义静态方法
WrappedComponent.staticMethod = function() {/*...*/}
// 使用高阶组件
const EnhancedComponent = enhance(WrappedComponent);

// 增强型组件没有静态方法
typeof EnhancedComponent.staticMethod === 'undefined' // true

Refs属性不能传递

HoC中指定的 ref,并不会传递到子组件,需要通过回调函数使用 props 传递。

参考链接

高阶组件

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
jqGrid随窗口大小变化自适应大小的示例代码
Dec 28 Javascript
原生js仿jq判断当前浏览器是否为ie,精确到ie6~8
Aug 30 Javascript
自定义jQuery插件方式实现强制对象重绘的方法
Mar 23 Javascript
Bootstrap每天必学之按钮
Nov 26 Javascript
基于zepto的移动端轻量级日期插件--date_picker
Mar 04 Javascript
js实现上传图片及时预览
May 07 Javascript
实例解析jQuery中proxy()函数的用法
May 24 Javascript
js简单获取表单中单选按钮值的方法
Aug 23 Javascript
jQuery基于正则表达式的表单验证功能示例
Jan 21 Javascript
JS实现图片放大镜插件详解
Nov 06 Javascript
javaScript产生随机数的用法小结
Apr 21 Javascript
JavaScript实现点击出现图片并统计点击次数功能示例
Jul 23 Javascript
基于react后端渲染模板引擎noox发布使用
Jan 11 #Javascript
Router解决跨模块下的页面跳转示例
Jan 11 #Javascript
vuex 使用文档小结篇
Jan 11 #Javascript
js判断传入时间和当前时间大小实例(超简单)
Jan 11 #Javascript
js点击时关闭该范围下拉菜单之外的菜单方法
Jan 11 #Javascript
纯js代码生成可搜索选择下拉列表的实例
Jan 11 #Javascript
web前端vue之vuex单独一文件使用方式实例详解
Jan 11 #Javascript
You might like
Extended CHM PHP 语法手册之 DIY
2006/10/09 PHP
PHP里8个鲜为人知的安全函数分析
2014/12/09 PHP
PHP使用PHPExcel删除Excel单元格指定列的方法
2016/07/06 PHP
JScript中的&quot;this&quot;关键字使用方式补充材料
2007/03/08 Javascript
javascript打开word文档的方法
2014/04/16 Javascript
javascript快速排序算法详解
2014/09/17 Javascript
NodeJS学习笔记之Connect中间件应用实例
2015/01/27 NodeJs
JavaScript实现网页对象拖放功能的方法
2015/04/15 Javascript
学习使用AngularJS文件上传控件
2016/02/16 Javascript
Vue.js 递归组件实现树形菜单(实例分享)
2016/12/21 Javascript
JS实现类似百叶窗下拉菜单效果
2016/12/30 Javascript
简单实现jQuery上传图片显示预览功能
2020/06/29 jQuery
vue-quill-editor+plupload富文本编辑器实例详解
2018/10/19 Javascript
在layui中使用form表单监听ajax异步验证注册的实例
2019/09/03 Javascript
layUI使用layer.open,在content打开数据表格,获取值并返回的方法
2019/09/26 Javascript
[14:57]DOTA2 HEROS教学视频教你分分钟做大人-幽鬼
2014/06/13 DOTA
[02:06]2018完美世界全国高校联赛秋季赛开始报名(附彩蛋)
2018/09/03 DOTA
[01:27:44]DOTA2-DPC中国联赛 正赛 PSG.LGD vs Aster BO3 第一场 1月24日
2021/03/11 DOTA
Python内置数据类型详解
2014/08/18 Python
Python 爬虫图片简单实现
2017/06/01 Python
详解python中的文件与目录操作
2017/07/11 Python
python学习笔记--将python源文件打包成exe文件(pyinstaller)
2018/05/26 Python
Flask框架web开发之零基础入门
2018/12/10 Python
基于python的ini配置文件操作工具类
2019/04/24 Python
使用turtle绘制五角星、分形树
2019/10/06 Python
浅谈python累加求和+奇偶数求和_break_continue
2020/02/25 Python
奥地利领先的在线药房:SHOP APOTHEKE
2019/10/07 全球购物
2014年创卫实施方案
2014/02/18 职场文书
单位作风建设自查报告
2014/10/23 职场文书
2014年新农村建设工作总结
2014/12/01 职场文书
2015年度公共机构节能工作总结
2015/05/26 职场文书
高中班主任培训心得体会
2016/01/07 职场文书
创业计划书之网吧
2019/10/10 职场文书
Go语言带缓冲的通道实现
2021/04/26 Golang
java泛型通配符详解
2021/07/25 Java/Android
Java实现注册登录跳转
2022/06/16 Java/Android