React Hooks (一文看懂四个常用的钩子)

上次看了阮一峰老师的文章,写的很通俗易懂,我在这简单给大家梳理一下

我们在开发中常用的就以下四个Hooks。

  1. useState()
  2. useContext()
  3. useReducer()
  4. useEffect()

1、useState():状态钩子

useState()用于为函数组件引入状态(state)。纯函数不能有状态,所以把状态放在钩子里面。
const [num,setNum] = useState<number>(1)
这一句代码是用白话说就是有个num变量,必须是number类型的(<>尖括号里边的是TYpescript限制类型的写法),初始值为一个数字1,然后setNum就是一个方法,通过一个前缀set就能看出来。setNum(10),通过set了一下,num的值就为10了。

<div onClick= {()=>setNum(10)}>

再看一个例子

import React, { useState } from "react";export default function  Button()  {const  [buttonText, setButtonText] =  useState("Click me,   please");function handleClick()  {return setButtonText("Thanks, been clicked!");}return  <button  onClick={handleClick}>{buttonText}</button>;
}

上面代码中,Button 组件是一个函数,内部使用useState()钩子引入状态。

useState()这个函数接受状态的初始值,作为参数,上例的初始值为按钮的文字。该函数返回一个数组,数组的第一个成员是一个变量(上例是buttonText),指向状态的当前值。第二个成员是一个函数,用来更新状态,约定是set前缀加上状态的变量名(上例是setButtonText)。

2、useContext():共享状态钩子

如果一个父组件有两个子组件,现在这两个子组件之间需要共享状态,就可以使用useContext

现在有两个组件 Navbar 和 Messages,我们希望它们之间共享状态。

<div className="App"><Navbar/><Messages/>
</div>

第一步就需要使用React Context API,在组件外部建一个Context。

const AppContext = React.creactContext({})

组件封装代码如下


<AppContext.Provider value={{username: 'superawesome'
}}><div className="App"><Navbar/><Messages/></div>
</AppContext.Provider>

上面代码中,AppContext.Provider提供了一个 Context 对象,这个对象可以被子组件共享。

在组件 Navbar 和 Messages中,我们可以通过使用const {username} = useContext(AppContext),拿到父组件的username了

const Navbar = () => {const { username } = useContext(AppContext);return (<div className="navbar"><p>AwesomeSite</p><p>{username}</p></div>);
}

3、useReducer():action 钩子

React 本身不提供状态管理功能,通常需要使用外部库。这方面最常用的库是 Redux。

Redux 的核心概念是,组件发出 action 与状态管理器通信。状态管理器收到 action 以后,使用 Reducer 函数算出新的状态,Reducer 函数的形式是(state, action) => newState

useReducers()钩子用来引入 Reducer 功能。

const [state, dispatch] = useReducer(reducer, initialState);

上面是**useReducer()的基本用法,它接受 Reducer 函数和状态的初始值作为参数,返回一个数组。数组的第一个成员是状态的当前值,第二个成员是发送**action 的dispatch函数。

下面是一个计数器的例子。用于计算状态的 Reducer 函数如下。

const myReducer = (state, action) => {switch(action.type)  {case('countUp'):return  {...state,count: state.count + 1}default:return  state;}
}

组件代码如下。

function App() {const [state, dispatch] = useReducer(myReducer, { count:   0 });return  (<div className="App"><button onClick={() => dispatch({ type: 'countUp' })}>+1</button><p>Count: {state.count}</p></div>);
}

4、useEffect():副作用钩子

什么是副作用?
看到这里,你可能会产生一个疑问:如果纯函数只能进行数据计算,那些不涉及计算的操作(比如生成日志、储存数据、改变应用状态等等)应该写在哪里呢?
函数式编程将那些跟数据计算无关的操作,都称为 “副效应” (side effect) 。如果函数内部直接包含产生副效应的操作,就不再是纯函数了,我们称之为不纯的函数。
纯函数内部只有通过间接的手段(即通过其他函数调用),才能包含副效应。

useEffect()本身是一个函数,由 React 框架提供,在函数组件内部调用即可。

举例来说,我们希望组件加载以后,网页标题(document.title)会随之改变。那么,改变网页标题这个操作,就是组件的副效应,必须通过useEffect()来实现。

import React, { useEffect } from 'react';function Welcome(props) {useEffect(() => {document.title = '加载完成';});return <h1>Hello, {props.name}</h1>;
}

上面例子中,useEffect()的参数是一个函数,它就是所要完成的副效应(改变网页标题)。组件加载以后,React 就会执行这个函数。
useEffect()的作用就是指定一个副效应函数,组件每渲染一次,该函数就自动执行一次。组件首次在网页 DOM 加载后,副效应函数也会执行

当然useEffect也有第二个参数,第二个参数是UseEffect的依赖项。

有时候,我们不希望useEffect()每次渲染都执行,这时可以使用它的第二个参数,使用一个数组指定副效应函数的依赖项,只有依赖项发生变化,才会重新渲染。

function Welcome(props) {useEffect(() => {document.title = `Hello, ${props.name}`;}, [props.name]);return <h1>Hello, {props.name}</h1>;
}

上面例子中,useEffect()的第二个参数是一个数组,指定了第一个参数(副效应函数)的依赖项(props.name)。只有该变量发生变化时,副效应函数才会执行。

如果第二个参数是一个空数组,就表明副效应参数没有任何依赖项。因此,副效应函数这时只会在组件加载进入 DOM 后执行一次,后面组件重新渲染,就不会再次执行。这很合理,由于副效应不依赖任何变量,所以那些变量无论怎么变,副效应函数的执行结果都不会改变,所以运行一次就够了。

只要是副效应,都可以使用useEffect()引入。它的常见用途有下面几种。

  1. 获取数据(data fetching)
  2. 事件监听或订阅(setting up a subscription)
  3. 改变DOM(changing the DOM)
  4. 输出日志(logging)

注意:使用useEffect()时,有一点需要注意。如果有多个副效应,应该调用多个useEffect(),而不应该合并写在一起。

React Hooks (一文看懂四个常用的钩子)相关推荐

  1. 一文看懂四种共享单车主流电子围栏技术

    共享单车之所以与中国的高铁,支付宝和网购一道,被老外称之为中国的新四大发明之一,就源于它以绿色环保,高效共享的方式解决了人们最后一公里出行问题.对比原来的有桩停放的"共享单车",现 ...

  2. 干货收藏!一文看懂8个常用Python库从安装到应用

    导读:Python本身的数据分析功能并不强,需要安装一些第三方扩展库来增强其相应的功能.本文将对NumPy.SciPy.Matplotlib.pandas.StatsModels.scikit-lea ...

  3. 从零开始系列(四):一文看懂arm架构和x86架构有什么区别

    从零开始系列(四):一文看懂arm架构和x86架构有什么区别 相关系列文章推荐:   从零开始系列(一):在github上搭建自己的博客   从零开始系列(二):数据库基础篇   从零开始系列(三): ...

  4. 一文看懂:互联网产品分析,该如何做?

    总有同学们在抱怨:"说的是做产品分析,可实际上每天都在埋点,建表,写SQL,对口径,找bug,我分析啥了?到底啥是产品分析?"今天简单分享一下. 所谓产品分析,特指对互联网产品:A ...

  5. 怎么看电脑系统是win几_一文看懂arm架构和x86架构有什么区别

    一文看懂arm架构和x86架构有什么区别 本文主要介绍的是arm架构和x86架构的区别,首先介绍了ARM架构图,其次介绍了x86架构图,最后从性能.扩展能力.操作系统的兼容性.软件开发的方便性及可使用 ...

  6. 决策树 随机森林 xgboost_一文看懂随机森林-RandomForest(附4个构造步骤+4种实现方式评测+10个优缺点)...

    随机森林是一种由决策树构成的集成算法,他在很多情况下都能有不错的表现.本文将介绍随机森林的基本概念.4 个构造步骤.4 种方式的对比评测.10 个优缺点和 4 个应用方向. 什么是随机森林? 随机森林 ...

  7. 华为p40pro手机计算机在哪里,一文看懂华为P40/P40 Pro差别在哪

    中关村在线消息:北京时间2020年3月26日,华为在线上举办新款旗舰产品发布会,会上发布了三款重量级手机新品:华为P40.华为P40 Pro和华为P40 Pro+. 在正式发布新品前,华为总裁余承东发 ...

  8. 干货|一文看懂什么是“非标资产”

    干货|一文看懂什么是"非标资产" 2017-05-19 18:56 监管/信托/资管 本文作者:中诚信托 一.非标资产的界定和范围 非标资产全称为非标准债权资产,是相对于标准化金融 ...

  9. AMBA总线协议(三)——一文看懂AHB总线所有协议总结(AHB2 AHB-Lite AHB5 )

    AMBA AHB 总线协议介绍请点击以下链接: AMBA总线协议(一)--一文看懂APB总线协议 AMBA总线协议(二)一文看懂AMBA2 AHB2与AMBA3 AHB-Lite总线协议的区别 AMB ...

最新文章

  1. 【Flutter】Flutter 应用创建运行 ( Android Studio 创建 / 运行 Flutter 应用 | 命令行创建 / 运行 Flutter 应用 )
  2. Codeforces #1063C Dwarves, Hats and Extrasensory Abilities
  3. arm开发tq2440上的c++裸奔程序
  4. 娄底二中高考2021成绩查询,2021年娄底高考状元名单公布,娄底高考状元学校资料及最高分...
  5. Hadoop动态修改LogLevel
  6. ios13.4.1续航怎么样?
  7. windows process activation service不能安装或启动的解决办法
  8. C#:在u3d中操作sqlite的数据库
  9. VirtualBox安装的Mac虚拟机,安装增强功能失败,应该是版本太新
  10. c语言大作业背单词,c语言必背代码 c语言入门必背单词 c语言必背100代码
  11. 中间件(一):订单系统整体架构
  12. 微博android4.1.2,Fuubo微博(新浪微博第三方客户端)app
  13. [图形学]OpenGL实现斯坦福兔子(Stanford Bunny)实验代码
  14. Linux下屏幕亮度的调节
  15. 基于Servlet和jsp的小说网站系统
  16. 你的贷款今天逾期了吗?
  17. 宝健中国用产品缔造口碑,深受消费者信赖
  18. 添加企业微信免验证设置
  19. 102 613 SWP协议学习笔记--数据链路层
  20. LogExplore简介

热门文章

  1. webinspect安全扫描
  2. 数字图像处理- 彩色图像转换为黑白图像
  3. blogs博客系统项目介绍
  4. c语言程序设计 医院,C语言程序设计(医院信息管理系统)附源代码(17页)-原创力文档...
  5. vue-amap(vue 地图)
  6. 基于Python的拼音汉字转换程序
  7. Java Excel 导出多个 sheet
  8. 微信小程序开发 image mode属性显示图片对应的格式详解
  9. .bat文件实现对Sql Server数据库的查询
  10. OpenCV自适应直方图均衡CLAHE图像和分块大小不能整除的处理