重复是不可能的,这辈子都不可能写重复的代码

当然,这句话分分钟都要被产品(领导)打脸,真的最后一次改需求,我们烦恼于频繁修改的需求

虽然我们不能改变别人,但我们却可以尝试去做的更好,我们需要抽象,封装重复的功能或者逻辑,而不是老旧的重复着机械的复制粘贴修改

那么我们如何去封装 React 中的组件以及逻辑呢?

这次我们来讲讲 React 里的高级组件

React 高级组件有两种方式:

  1. 使用高阶组件( Higher Order Component ==> HOC )
  2. 子组件作为函数的模式( Render Props )

高阶组件

首先来说说高阶组件,它不是 React 的提供的 API,它是模式,一种增强组件的模式,简单来说其实就是高阶函数,高阶函数大家应该不陌生

高阶函数 : 把函数作为参数传入,返回一个新的函数,这样的函数称为高阶函数

而所谓的高阶组件也就是传入一个现有组件作为参数,返回一个新的组件,高阶租价也分为代理方式和继承方式

我们先来看看一个简单的 HOC :

import React from 'react';

function addNameProp(WrapperComponent) {
return class extends React.Component {
render() {
const { name, ...props } = this.props;
return <WrapperComponent {...props} name={name || 'cnyballk'} />;
}
};
} export default addNameProp;

在上面的代码里我们定义了一个 addNameProp。 函数,它的作用就是为没有传入 name 的 prop 传入的组件添加一个 name 的 prop ,然后渲染出来

这个高阶组件就完成了对传入组件的增强,这也是一个代理方式的高阶组件

那么继承方式是怎么样的呢

import React from 'react';

function addNameProp(WrapperComponent) {
return class extends WrapperComponent {
render() {
this.props = {
...this.props,
name: this.props.name || 'cnyballk',
};
return super.render();
}
};
} export default addNameProp;

和上面的高阶组件 一样的效果,而继承模式和代理模式最大的区别就是一个是返回传入的组件,一个是调用继承的父组件的 render 方法

⚠️ 在代理模式下 WrapperComponent 经历了完整的生命周期,返回的组件也有一次完整的生命周期,而继承模式 则是调用了 WrapperComponent 的 render ,只有返回的组件的一个生命周期

如果我们用过 react-redux 的 connect 也就知道 connect 也是一个代理模式的高阶组件

⚠️ 高阶组件可以这么使用

@Wrapper
class Index extends Component {
...略
}

emmmm...这个涉及到 js 的装饰器,各位自己去搜来学习哈

Render Props

那么我们已经认识了高阶组件的重用方法,也认识到了高阶组件的优点。

但是高阶组件的缺点是什么呢?

相信你们也能看到了,我们传递一个 name 的 Prop ,那是不是得传入的组件能够处理才可以,而且还有命名的冲突危险,毕竟有些组件的 props 命名各有不同,或者说子组件需要同一份数据处理方式却不一样,所以说这个时候就不适用 HOC 了

HOC 对于使用者来说是一个黑盒,还需要去看他们的实现

而 Render Props 则是 数据给你,其他的你自己来

我们来看一个简单的例子

import React from 'react';

class AddNameProp extends React.Component {
render() {
const name = 'cnyballk';
return this.props.children(name);
}
} export default AddNameProp;

简单的使用

<AddNameProp>{name => <div>我叫 {name}</div>}</AddNameProp>

想传递给组件

<AddNameProp>
{name =>
<Hello name={name}/>;
}
</AddNameProp>

或者是其他的 prop 名

<AddNameProp>
{name =>
<Hello myName={name}/>;
}
</AddNameProp>

我们可以看到,这个方式很灵活,因为子组件是一个函数,一切皆有可能,但是 Render Props 也有缺点就是难以做性能优化,高阶组件可以利用 SCU 来避免重复渲染。虽然这样,,Render Props 却是一个非常好(牛逼)的一个模式,我很喜欢

Render Props VS HOC

我们能够清楚的明白,HOC是一种粗粒度的代码复用,而Render Props是一种细粒度的复用,他们可以互换,我们什么时候用HOC,什么时候用Render Props相信大家也差不多清楚了

小结

本文介绍了 React 的高级组件的两个方式,各有优缺点,但它们都是为了重用代码,我们可以自己选择喜欢的模式去做,但是不要复制粘贴了,感受封装复用的力量

高阶组件代理模式可以更好的控制和实现,继承模式则可以控制特定组件的生命周期,与高阶组件相比, Render Props 模式更加灵活,有函数,我们可以更自由

可复用 React 的 HOC 以及的 Render Props的更多相关文章

  1. React高阶组件 和 Render Props

    高阶组件 本质 本质是函数,将组件作为接收参数,返回一个新的组件.HOC本身不是React API,是一种基于React组合的特而形成的设计模式. 解决的问题(作用) 一句话概括:功能的复用,减少代码 ...

  2. [React] Use Prop Collections with Render Props

    Sometimes you have common use cases that require common props to be applied to certain elements. You ...

  3. 学习React系列(十)——Render Props

    解决问题:将行为封装,供多个组件使用(在多个组件之间分享某段代码) 组件中的props属性中包含一个"render"属性(该属性为一个返回值为元素的方法),然后在该组件的rende ...

  4. React-代码复用(mixin.hoc.render props)

    前言 最近在学习React的封装,虽然日常的开发中也有用到HOC或者Render Props,但从继承到组合,静态构建到动态渲染,都是似懂非懂,索性花时间系统性的整理,如有错误,请轻喷~~ 例子 以下 ...

  5. React中render Props模式

    React组件复用 React组件复用的方式有两种: 1.render Props模式 2.高阶组件HOC 上面说的这两种方式并不是新的APi. 而是利用Raect自身的编码特点,演化而来的固定编码写 ...

  6. React Render Props 模式

    概述 Render Props模式是一种非常灵活复用性非常高的模式,它可以把特定行为或功能封装成一个组件,提供给其他组件使用让其他组件拥有这样的能力,接下来我们一步一步来看React组件中如何实现这样 ...

  7. React 之 render props 的理解

    1.基本概念 在调用组件时,引入一个函数类型的 prop,这个 prop定义了组件的渲染方式. 2.回调渲染 回顾组件通信的几种方式 父-> 子 props 子-> 父 回调.消息通道 任 ...

  8. [Recompose] Refactor React Render Props to Streaming Props with RxJS and Recompose

    This lesson takes the concept of render props and migrates it over to streaming props by keeping the ...

  9. render props的运用

    2020-04-03 render props的运用 术语 “render prop” 是指一种在 React 组件之间使用一个值为函数的 prop 共享代码的简单技术 通常的 这个值为函数的prop ...

随机推荐

  1. Murano Weekly Meeting 2015.08.18

    Meeting time: 2015.August.18th 1:00~2:00 Chairperson:  Nikolay Starodubtsev, from Mirantis Meeting s ...

  2. C#入门--字段与属性

    C#入门--字段与属性 “字段”,它是包含在类或结构中的对象或值.字段使类和结构可以封装数据. 属性是这样的成员:它们提供灵活的机制来读取.编写或计算私有字段的值.可以像使用公共数据成员一样使用属性, ...

  3. intellijidea课程 intellijidea神器使用技巧 6-1 Spring的关联

    待学完spring之后再来看 Spring的关联位置:菜单->File->Project Structure->Facets功能:帮助管理Spring容器.还提供了很多其他的管理,比 ...

  4. JavaScript 对象继承 OOP (三)

      对象继承 A 对象通过继承 B 对象,就能直接拥有 B 对象的所有属性和方法.这对于代码的复用是非常有用的. JavaScript 语言的继承不通过 class (es6 中的class 不过是 ...

  5. MarkDown 编辑器学习

    MarkDown 编辑器学习 是一种简单快键的文字排版工具,可以用于编写说明文档,鉴于其语法简洁明了,且其渲染生成的样式简单美观,很多开发者也用它来写博客,已被国内外很多流行博客平台所支持.生成的文件 ...

  6. >>我要做特工系列 之 CSS 3_animation_向右滑出后下滑并停止

    新手入门还没有正式发点啥东西,都是在装潢博客这个家了,到现在为止还是没有装修好..熟悉了这边的发布规范之后会持续在这里记录,给自己留下学习的脚印~ 这正式的第一篇随笔写个使用css3的动画效果. 总感 ...

  7. 零基础逆向工程39_Win32_13_进程创建_句柄表_挂起方式创建进程

    1 进程的创建过程 打开系统 --> 双击要运行的程序 --> EXE开始执行 步骤一: 当系统启动后,创建一个进程:Explorer.exe(也就是桌面进程) 步骤二: 当用户双击某一个 ...

  8. Dynamics CRM用户创建后自动添加到团队报错

    前两天在实现一项需求——用户创建后自动添加到一个叫做“全体员工”的团队的时候,遇到了一个奇怪的错误,CRM的错误日志只有一句简单的“Generic SQL error.”.一般遇到这个错误处理都非比较 ...

  9. 什么是TOPO学

    拓扑,一个跟门萨同样古怪的“科技Word”.其定义,对绝大多数读者而言,不一定需要理解,但无妨知道———拓扑学,数学的一门分科,研究几何图形在一对一的双方连续变换下不变的性质.不少门萨题,来自拓扑学, ...

  10. 【Unity3D学习笔记】解决放大后场景消失不显示问题

    不知道为啥,我的Unity场景放大到一定大小后,就会消失... 解决方案: 选中一个GameObject,然后按F键. F键作用是聚焦,视图将移动,以选中对象为中心.