目录

  • 前言
  • 一、react 内置的 Hook
    • 1、useState
    • 2、useEffect
  • 二、自定义 Hook
  • 三、使用 hook 遇到的问题
    • 1、react 函数组件使用了 hook 后闪屏

前言

在 React 16.8 之前,React 的 function 组件也称为无状态组件,因为 function 组件既不能访问 react 生命周期,也没有自己的状态。
自 React 16.8 起引入了 Hooks 概念,使得 function 组件可以通过 Hooks 模拟对应的 class 组件的生命周期,并且拥有了自己的状态。

Hook 是能在 function 组件里“钩入” React state 及生命周期等特性的 JavaScript 函数。

Hook 函数的使用规则:

  • 可以在 React function 组件中调用 Hook,不能在 class 组件中调用 Hook(这使得你不使用 class 也能使用 React)。
  • 可以在自定义的 Hook 函数中调用 Hook。
  • 只能在函数最外层调用 Hook,不能在循环、条件判断或者子函数中调用 Hook。

React 官方提供了一个 linter 插件来强制执行 Hook 的规则。

一、react 内置的 Hook

1、useState

useState 只在初始化时执行一次,后面不再执行。

语法:

const [state变量, 设置该变量的方法] = useState(初始值);

通过在函数组件里调用 useState 来给组件添加一些内部 state:

  • React 会在重复渲染时保留这个 state。
  • useState 会返回一对值:当前状态和一个让你更新它的函数,你可以在事件处理函数中或其他一些地方调用这个函数。它类似 class 组件的 this.setState,但是它不会把新的 state 和旧的 state 进行合并。

2、useEffect

React useEffect清理:如何以及何时使用它

useEffect 是 class 组件中的 componentDidMount,componentDidUpdate 和 componentWillUnmount 这三个函数的组合 API,可以通过传参及其他逻辑,分别模拟这三个生命周期函数:

  • useEffect 第二个参数是一个数组,如果数组为空时,则只执行一次(相当于componentDidMount)。
  • 如果数组中有值时,则该值更新时,useEffect 中的函数才会执行(相当于componentDidUpdate)。
  • 如果没有第二个参数,则每次render时,useEffect 中的函数都会执行。

React 保证了每次运行 effect 的同时,DOM 都已经更新完毕,也就是说 effect 中的获取的 state 是最新的,但是需要注意的是,effect 中返回的函数(其清除函数)中,获取到的 state 是更新前的。

传递给 useEffect 的函数在每次渲染中都会有所不同,这是刻意为之的。事实上这正是我们可以在 effect 中获取最新的值,而不用担心其过期的原因。每次我们重新渲染,都会生成新的 effect,替换掉之前的。某种意义上讲,effect 更像是渲染结果的一部分 —— 每个 effect 属于一次特定的渲染。

effect 的清除阶段(返回函数)在每次重新渲染时都会执行,而不是只在卸载组件的时候执行一次。它会在调用一个新的 effect 之前对前一个 effect 进行清理,从而避免了我们手动去处理一些逻辑 。

二、自定义 Hook

创建你自己的 Hook

自定义 Hook 是一个函数,函数名以 “use” 开头,函数内部可以调用其他的 Hook。它更像是一种约定而不是功能。

自定义 Hook 是一种自然遵循 Hook 设计的约定,而并不是 React 的特性。

通过自定义 Hook,可以将组件逻辑提取到可重用的函数中。

例如:

// 组件 FriendStatus 中
import React, { useState, useEffect } from 'react';function FriendStatus(props) {const [isOnline, setIsOnline] = useState(null);useEffect(() => {function handleStatusChange(status) {setIsOnline(status.isOnline);}ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);return () => {ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);};});if (isOnline === null) {return 'Loading...';}return isOnline ? 'Online' : 'Offline';
}
// 组件 FriendListItem 中
import React, { useState, useEffect } from 'react';function FriendListItem(props) {const [isOnline, setIsOnline] = useState(null);useEffect(() => {function handleStatusChange(status) {setIsOnline(status.isOnline);}ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);return () => {ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);};});return (<li style={{ color: isOnline ? 'green' : 'black' }}>{props.friend.name}</li>);
}

在组件 FriendStatus 和 FriendListItem 中,有公共的代码部分如下:

const [isOnline, setIsOnline] = useState(null);
useEffect(() => {function handleStatusChange(status) {setIsOnline(status.isOnline);}ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);return () => {ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);};
});

此时,就可以使用自定义 hook 将这公共的部分提取出来供这两个组件引用。该自定义 hook 的实现如下:

// 自定义 useFriendStatus hook
import { useState, useEffect } from 'react';export function useFriendStatus(friendID) {const [isOnline, setIsOnline] = useState(null);useEffect(() => {function handleStatusChange(status) {setIsOnline(status.isOnline);}ChatAPI.subscribeToFriendStatus(friendID, handleStatusChange);return () => {ChatAPI.unsubscribeFromFriendStatus(friendID, handleStatusChange);};});return isOnline;
}

三、使用 hook 遇到的问题

1、react 函数组件使用了 hook 后闪屏

闪屏的原因分析与解决思路:

  • 页面渲染,没有 loading 状态。(给页面添加 loading 状态,给会导致页面回流重绘的接口添加 loading 状态)
  • 实时更新的数据没有更新。(使用 useState + useEffect 机制创建与监听实时更新的数据)

React 之 function 组件里使用 Hooks相关推荐

  1. react高阶组件、hooks

    1.高阶组件 1.1概念 高阶组件(简称:HOC):是react中用于重用组件逻辑的高级技术,它本身不是react中的组件,而是一个函数.这个函数接受一个react组件作为参数,并返回一个新组件,实现 ...

  2. react高阶组件和hooks

    1. react高阶组件 1.1 高阶组件的概念 高阶组件(Higher Order Component,简称:HOC ): 是 React 中用于重用组件逻辑的高级技术, 它本身不是react中的组 ...

  3. react 动态添加组件属性_这么高质量React面试题(含答案),看到就是赚到了!...

    前言 本文篇幅较长,全是干货,建议亲们可以先收藏慢慢看哦 写文不易,欢迎大家一起交流,喜欢文章记得关注我点个赞哟,感谢支持! Q1 :什么是虚拟DOM? 难度::star: 虚拟DOM(VDOM)它是 ...

  4. react 数组新增_React 新特性 Hooks 讲解及实例(二)

    本文是 React 新特性系列的第二篇,第一篇请点击这里: React 新特性讲解及实例 什么是 Hooks Hook 是 React 16.8 的新增特性.它可以让你在不编写 类组件 的情况下使用 ...

  5. 「react进阶」一文吃透React高阶组件(HOC)

    一 前言 React高阶组件(HOC),对于很多react开发者来说并不陌生,它是灵活使用react组件的一种技巧,高阶组件本身不是组件,它是一个参数为组件,返回值也是一个组件的函数.高阶作用用于强化 ...

  6. react 显示隐藏组件的方法_10种React组件之间通信的方法

    来源 | https://segmentfault.com/a/1190000023585646 这两天被临时抽调到别的项目组去做一个小项目的迭代.这个项目前端是用React,只是个小型项目所以并没有 ...

  7. React 2019年路线图发布!Hooks明年一季度上线

    你可能在之前的一些文章和演讲中听过"Hooks"."Suspense"和"并发渲染"等新特性. 在这篇文章中,我们将介绍它们在React稳定 ...

  8. react实现汉堡_利用 React 高阶组件实现一个面包屑导航

    什么是 React 高阶组件 React 高阶组件就是以高阶函数的方式包裹需要修饰的 React 组件,并返回处理完成后的 React 组件.React 高阶组件在 React 生态中使用的非常频繁, ...

  9. react如何卸载组件_18道 React 面试必考题含解答面试高频

    前言 React 前端框架的受欢迎程度丝毫木有减弱的迹象,全国许多城市对开发人员仍供不应求.对于经验不足的开发人员(或那些已经失业了一段时间的开发人员),在面试阶段展示您的知识可能会令人生畏. 在本文 ...

最新文章

  1. 使用 Vue 2.0 实现服务端渲染的 HackerNews
  2. Nginx 配置实战:负载均衡的实现
  3. oracle断开不活跃链接,活跃进程连接导致数据库迟迟未关闭
  4. web scraper 抓取网页数据的几个常见问题
  5. 动态规划求解序列问题(LIS、JLIS)
  6. ITK:计算网格的法线
  7. HDU1421 搬寝室
  8. Pytorch常用操作
  9. Pyecharts绘制22种超实用精美图表
  10. Spring Boot Starter 常用列表
  11. Leetcode每日一题:242.有效的字母异位词
  12. Springboot(java)程序部署到k8s
  13. git本地仓库基本使用(Repository)
  14. matlab ROR半径滤波
  15. jquery.nicescroll.min.js滚动条插件的用法
  16. 要闻君说: 百度云喜提信息安全首证;紫光展锐携5G芯片进击2019MWC;OPPO首发5G手机惊艳亮相……...
  17. 常用的大功率电阻有哪些,电阻功率降额设计要注意什么
  18. Docker 取代 VM !是什么让 Docker 比 VM 或裸机更安全?
  19. 【控制篇 / 应用】(6.0) ❀ 01. 只允许使用 QQ 和微信 (上) ❀ FortiGate 防火墙
  20. servlet使用监听器统计网站在线人数

热门文章

  1. python会不会内存泄露_记一次python 内存泄漏问题及解决过程 python 嵌套读取文件 内存泄露...
  2. GDUT 排位赛2.19 C
  3. 开源的 Restful Api 集成测试工具 Hitchhiker
  4. 北斗定位背后的数学秘密
  5. 椰青文案:椰青水果促销活动策划文案,朋友圈椰青水果文案
  6. chrome 插件 页面请求转发_入门chrome插件开发教程和经验总结,一篇就搞掂!
  7. 优质 CS 读博 (PhD) 经验贴汇总
  8. vue响应式简单实现
  9. springboot基于vue的MOBA类游戏攻略分享平台
  10. 融云即时通讯之直播聊天室