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 相关文章推荐
js类后台管理菜单类-MenuSwitch
Sep 12 Javascript
Javascript 篱式条件判断
Aug 22 Javascript
深入理解JavaScript系列(6) 强大的原型和原型链
Jan 15 Javascript
js和as的稳定传值问题解决
Jul 14 Javascript
js实现鼠标划过给div加透明度的方法
May 25 Javascript
在JS中操作时间之getUTCMilliseconds()方法的使用
Jun 10 Javascript
BOM系列第三篇之定时器应用(时钟、倒计时、秒表和闹钟)
Aug 17 Javascript
js中document.referrer实现移动端返回上一页
Feb 22 Javascript
vuex 的简单使用
Mar 22 Javascript
vue写一个组件
Apr 09 Javascript
微信小程序实现红包雨功能
Jul 11 Javascript
js实现登录时记住密码的方法分析
Apr 05 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
PHP 面向对象程序设计(oop)学习笔记 (四) - 异常处理类Exception
2014/06/12 PHP
PHP中比较时间大小实例
2014/08/21 PHP
PHP isset()与empty()的使用区别详解
2017/02/10 PHP
Laravel中Facade的加载过程与原理详解
2017/09/22 PHP
Laravel 框架路由原理与路由访问实例分析
2020/04/14 PHP
一个可以显示阴历的JS代码
2007/03/05 Javascript
javascript级联下拉列表实例代码(自写)
2013/05/10 Javascript
js实现文章文字大小字号功能完整实例
2014/11/01 Javascript
jQuery对象和DOM对象之间相互转换的方法介绍
2015/02/28 Javascript
js中函数声明与函数表达式
2015/06/03 Javascript
Bootstrap3制作自己的导航栏
2016/05/12 Javascript
基于JavaScript实现跳转提示页面
2016/09/24 Javascript
纯原生js实现贪吃蛇游戏
2020/04/16 Javascript
node.js基于express使用websocket的方法
2017/11/09 Javascript
webpack 打包压缩js和css的方法示例
2018/03/20 Javascript
jQuery实现列表的增加和删除功能
2018/06/14 jQuery
微信小程序云开发实现云数据库读写权限
2019/05/17 Javascript
vue仿ios列表左划删除
2019/09/26 Javascript
JS控制下拉列表左右选择实例代码
2020/05/08 Javascript
微信小程序文章列表功能完整实例
2020/06/03 Javascript
在vue中给后台接口传的值为数组的格式代码
2020/11/12 Javascript
详解Django中的权限和组以及消息
2015/07/23 Python
python UNIX_TIMESTAMP时间处理方法分析
2016/04/18 Python
Python生成短uuid的方法实例详解
2018/05/29 Python
python3使用SMTP发送HTML格式邮件
2018/06/19 Python
python多进程使用及线程池的使用方法代码详解
2018/10/24 Python
python requests.post带head和body的实例
2019/01/02 Python
python自动化测试之如何解析excel文件
2019/06/27 Python
Python定时器线程池原理详解
2020/02/26 Python
集世界奢侈品和设计师品牌的意大利精品买手店:Tessabit
2019/08/17 全球购物
优秀的2014年两会精神解读
2014/03/17 职场文书
房屋买卖委托书格式范本格式
2014/10/13 职场文书
机关党员四风问题个人整改措施
2014/10/26 职场文书
质量整改通知单
2015/04/21 职场文书
2015年音乐教师个人工作总结
2015/05/20 职场文书
买卖合同纠纷代理词
2015/05/25 职场文书