前言

  这里写一下如何封装可复用组件。首先技术栈 react hooks + props-type + jsx封装纯函数组件。类组件和typeScript在这不做讨论,大家别白跑一趟。

接下来会说一下封装可复用组件的思路,比如一个新手应该怎么去封装,都需要有哪些东西。

  然后说一些复杂组件需要的功能,比如闭合标签内部dom怎么处理,其实就是插槽功能,比如数据监听,内部做一些业务逻辑。

  想看原码的点这里,这是一个GitHub上完整的 react hooks 项目,  点这里,看源码

目录

1、思路 及 封装的误区

2、 props 的类型检测、默认值

3、父子组件与他的数据互通

4、实现类似于vue插槽一样的功能 (children属性)

5、useState、useEffect等hooks讲解

6、总结

一、思路

  无论是js还是C++等等,都要求 模块内高内聚、模块间低耦合。简单点说就是你改了一个模块,另一个模块稍作修改就行,不至于改动很大。根据这个编程思想,一个可复用的组件的对外交互,就是决定他耦合度的关键。把组件比作香肠机,输入猪肉,输出香肠。输入就是props,输出就是界面效果 以及 给外部反馈的回调函数。关于输入props,我们对他有要求,就是类型检查和默认值。比如输入的得是猪肉不能是石头,默认做小香肠,而不是大香肠。回调函数也有要求,你得尽可能满足可以预知的逻辑,简单说就是你以后用这个组件的时候,需要某个数据,这个组件得支持,得有对应的回调。

  注意,这里说几个误区,也是很多新手经常犯错的地方。

  1、项目中可复用组件我认为有2种,而不是所有组件都按照一套标准去规范

    第一种 全局可复用组件,这类组件类似于antd那种ui库,是提供给开发项目所有人使用的,频率高。这一类必须严格规范,不能乱搞。必须有props的类型检查,有需要给props加默认值;组件内部只能通过props修改,通过回调函数反馈,严禁其他任何形式的修改;必须对组件功能,props,内部的方法等添加注释。

    第二种 是一些局部功能组件,这一类可能只在部分特定情况下会使用,不需要像第一种那种严格要求,比较灵活多变,尽可能以简单通俗易懂去编写他,比如接下来要描述的几种禁忌,这类组件并没有这些要求,只要代码精简、便于维护、易读。你想怎么写都行。就这么豪横。

  2、全局组件

    避免使用redux一类的状态管理,能用props实现就别懒

    避免使用ref获取组件数据,能用回调的都写上回调,ref可读性很差

    保持纯净,自己开发的可以相互引用,但是尽可能避免对第三方、包括UI框架的使用。当然这也不是绝对,二次封装组件很常见,只是有条件的尽量自己开发。

二、 props 的类型检测、默认值

  我们使用prop-types做props类型检查,得安装一下

  npm i prop-types

  看下面的代码,首先引入 prop-types ,然后创建我们的函数组件,这里有奇点需要注意的,首先,先定义组件,然后在组件原型上做绑定类型检查;其次因为函数组件,所有用props-types做类型检查的props,必须在函数组件的形参中显式的声明,否则不好使。看代码也能理解毕竟绑定在原型上,初始化的时候不声明,就没办法绑定校验了。所以,我建议一种写法,所有props都做检查,都在形参中声明,能赋默认值的,都写上默认值,然后在形参的后面把注释都写明白了,这样代码一目了然,换个人可以很容易接手你的代码。这里啰嗦一嘴,函数组件,本质就是个函数,所以默认值这些都是js函数形参赋默认值的写法。

  额外啰嗦两句prop-types的用法,后面这个是他的用法说明:  https://zh-hans.reactjs.org/docs/typechecking-with-proptypes.html

  包括所有的类型、一个props声明多个类型,对象内部属性的类型校验,甚至是定义一个类型检查的函数

三、父子组件与他的数据互通

  处理好了props,我们处理回调,如图所示,是我写的一个简单的回调,这里一般不写默认值,但是要做非空判断,因为不是所有的属性,使用者都需要。

 四、实现类似于vue插槽一样的功能 (children属性)

  封装组件经常会遇到需要 插槽 的情况,简单说就是一个闭合组件,内部的dom你想对他做一些处理,比如样式上的。这里说一下改怎么做。看图,注意一下,如果有一个根标签,children就是个对象,如果多个并列标签的话,children就是数组,用法不一样,这里根据需求来,我这里用的是对象,注意需要定义children的类型,是标签,还是一个数组的标签

五、useState、useEffect等hooks讲解

  最后写一点函数组件的使用心得。首先父组件变化 或者 函数组件内部变量变化,都会导致函数组件重新执行,如果你在return前面写个console,会发现执行了很多次,复杂的界面甚至能执行几十次,这点很操蛋,不过最终diff的时候react会做优化,合并很多变化。而且,函数组件只有hooks,没有生命周期,这些和类组件差异很大,代码逻辑也改变很大。

  1、函数会不断执行,如果在函数内部声明变量或者常量会不断赋值,所以要么用useState声明要么直接放到函数外,比如标记1、3 、4。大家避免写出死循环哈。

  2、useState声明的变量,默认值智慧赋值一次,比如标记 2

  3、函数组件没生命周期,useEffect 用于监听变量变化,可以监听useState的也可以监听我们那个标记1这种函数外的。他第二个参数传空数组,就只会在组件初始化的时候执行一次,可以在这初始化数据,发http请求,或者时间绑定等。他的触发机制实在dom渲染结束之后。比如标记 5

  4、useMemo 通过这个hooks可以优化组件的渲染次数,是根据指定变量变化触发函数执行的

u

六、总结

  关于react hooks封装可复用组件,暂时就想到了这么多,文章开头我贴了GitHub的项目地址,因为要说的东西比较多,没法一个例子就把所有东西清晰、条理的说明白,期间我截图了好几个组件的代码,大家看源码的话,直接看components文件夹。

react hooks 如何自定义组件(react函数组件的封装)的更多相关文章

  1. React - 组件:函数组件

    目录: . 组件名字首字母一定是大写的 . 返回一个jsx . jsx依赖React,所以组件内部需要引入React . 组件传参 a. 传递. <Component list={ arrDat ...

  2. React Hooks 深入系列 —— 设计模式

    本文是 React Hooks 深入系列的后续.此篇详细介绍了 Hooks 相对 class 的优势所在, 并介绍了相关 api 的设计思想, 同时对 Hooks 如何对齐 class 的生命周期钩子 ...

  3. React Hooks用法大全

    前言 在 React 的世界中,有容器组件和 UI 组件之分,在 React Hooks 出现之前,UI 组件我们可以使用函数,无状态组件来展示 UI,而对于容器组件,函数组件就显得无能为力,我们依赖 ...

  4. React Hooks究竟是什么呢?

    摘要: React Hooks原理解析. 原文:快速了解 React Hooks 原理 译者:前端小智 我们大部分 React 类组件可以保存状态,而函数组件不能? 并且类组件具有生命周期,而函数组件 ...

  5. React Hooks总结

    Hook 前言 什么是Hook 自从 16.8 版本开始,hooks 的出现使得你可以在不编写 class 的情况下使用状态管理以及其它 React 的特性. 那么在 React Hooks 出现之前 ...

  6. React Hooks的理解

    一.是什么 Hook 是 React 16.8 的新增特性.它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性 至于为什么引入hook,官方给出的动机是解决长时间使 ...

  7. React Hooks介绍和环境搭建(一)

    React Hooks 简介 2018年底FaceBook的React小组推出Hooks以来,所有的React的开发者都对它大为赞赏.React Hooks就是用函数的形式代替原来的继承类的形式,并且 ...

  8. [React Hooks长文总结系列一]初出茅庐,状态与副作用

    写在开头 React Hooks在我的上一个项目中得到了充分的使用,对于这个项目来说,我们跳过传统的类组件直接过渡到函数组件,确实是一个不小的挑战.在项目开发过程中也发现项目中的其他小伙伴(包括我自己 ...

  9. React 函数组件中对window添加事件监听resize导致回调不能获得Hooks最新状态的问题解决思路

    React 函数组件中对window添加事件监听resize导致回调不能获得Hooks最新状态的问题解决思路 这几天在忙着把自己做的项目中的类组件转化为功能相同的函数组件,首先先贴一份该组件类组件的关 ...

随机推荐

  1. 巩固java第六天

    巩固内容: HTML 空元素 没有内容的 HTML 元素被称为空元素.空元素是在开始标签中关闭的. <br> 就是没有关闭标签的空元素(<br> 标签定义换行). 在 XHTM ...

  2. apostrophe

    apostrophe 者,', 0x27, 十进制39,ASCII里的single quote (单引号) 也.one of the 'inverted commas'. 在书写上可以表示所有格.省略 ...

  3. day13 cookie与session和中间件

    day13 cookie与session和中间件 今日内容概要 cookie与session简介 django操作cookie与session django中间件简介 如何自定义中间件 csrf跨站请 ...

  4. day01互联网架构理论

  5. 零基础学习java------31---------共享单车案例,html快速入门(常见标签,get和post的区别)

     一 .单车案例 二. HTML快速入门 红字表示要掌握的内容 超文本标记语言,此处的标记指的即是关键字,其用处是用来写页面(展示数据). 语法:(1)./当前目录:../ 父级目录 (2)注释符号: ...

  6. map和forEach的区别

    总结 forEach()可以做到的东西,map()也同样可以.反过来也是如此. map()会分配内存空间存储新数组并返回,forEach()不会返回数据. forEach()允许callback更改原 ...

  7. Java实现 HTTP/HTTPS请求绕过证书检测

    java实现 HTTP/HTTPS请求绕过证书检测 一.Java实现免证书访问Https请求 创建证书管理器类 import java.security.cert.CertificateExcepti ...

  8. C# 温故知新 第一篇 C# 与 .net 的关系

    C# 与.net 的关系很多初学者或者未从事过.net 研发的编程人员 都不是很清楚,认为 C# 与.net 是一回事. 我们经常说java开发,C++开发,指的是两种开发语言:但是 经常看到 .ne ...

  9. C# 枚举的flags 标志位应用

    枚举有个特性叫标志位,使用方法如下 [Flags] enum Foo { a =1, b = 2, c = 4, d = 8 } 每个值需要为2的n次方,保证多个值的组合不会重复. 这样在判断其中一个 ...

  10. 04 - Vue3 UI Framework - 文档页

    官网的首页做完了,接下来开始做官网的文档页 返回阅读列表点击 这里 路由设计 先想想我们需要文档页通向哪些地方,这里直接给出我的设计: 所属 子标题 跳转路径 文件名(*.vue) 指南 介绍 /do ...