React Hook的用法: State + Effect(一)
React Hook
简述
React Hook 是React 16.8 这个版本新增的一个特性。在此之前我们编写React组件一般大多数都是用 class组件,而非函数组件,因为函数组件不具有class组件的状态,生命周期这些概念,这就使得在使用函数组件的时候有很多掣肘。而class组件与函数组件相比明显略笨重,很多不必要冗余的模板代码,而且还有this的问题,要么使用箭头函数,要么每次需要bind一下this。但是如果使用了Hook那就可以很好的规避了这些问题。下面就简单介绍一下Hook的用法
State Hook
Hook即钩子,使用的时候都是 use打头,后面再加上具体的钩子,所以就是 useXXX的样子。
state hook 使得函数组件具有了自己的状态,类似class组件中可以通过 state来记录组件状态一样。每次当函数组件的状态的值发生改变的时候,对应的函数组件也会相应的做更新,下面看下用法。
// 需要使用 state 这个 钩子就先将其引入
import React, { useState } from 'react';
const initAge = 20;
const [age, setAge] = useState(initAge);
// 按照上述的方式定义好之后就可以直接使用了,在 render函数中可以像下面这样直接使用和更新 age的值
<Button type="primary" onClick={()=>setAge(age+1)} className='ml10'>add age</Button>
上述代码的几点说明
- useState接受一个变量的初始值(在这里是 initAge)
- 返回的是这个初始值的变量(age)和修改这个初始值的方法(setAge)
- 根据useState的返回值,我们一般结合结构赋值写成 const [age, setAge] = useState(initAge); 这种形式
注意在这里一般 我们用于接受变量的值是 xx的话(这里是age),那么用于修改这个值的变量就在前面加上 setxx(这里是 setAge);
具体效果如下:
点击查看线上Demo
可以看到,当我们引入了 state 这个钩子的时候就可以达到class 组件中状态的效果了
Effect Hook
上面的部分使得函数组件具有了记录自己状态的功能,但毕竟不是所有的组件都是“傻瓜”组件,只需要根据外部传入的数据做单纯的渲染即可,作为功能较复杂的大型业务组件有时候需要在合适的时候做一些特殊的业务操作,比如组件刚渲染的时候发出http请求服务端数据,组件销毁的时候去注销一些事件(比如滚动监听事件)避免性能的额外开销,每次点击年龄增加的时候需要发送数据给server等等,这就需要引入 Effect 副作用这个钩子。
组件创建
比如看下面这个例子,组件在刚刚渲染的时候会请求服务端的数据,然后将请求的数据展示更新在页面上:
使用 useEffet 这个钩子可以接受一个函数,该函数就是在组件渲染的时候会被执行,有点类似class组件中的 componentDidMount 生命周期。
点我查看在线Demo
组件销毁
下面看一下当组件会被销毁的时候执行一些业务操作该如何书写。
这个例子被设计为父组件包含一个函数子组件,函数子组件每次被父组件销毁的时候可以在子组件中触发一个事件钩子暴露给业务开发者,使得开发者可以在这个事件钩子中处理自己需要处理的业务,比如注销所监听的滚动事件,或者是发送请求到server端。
useEffect第一个参数接受一个函数,该函数会在该组件被创建的时候执行,同时这个函数也能 return 另一个函数,而return 的函数就是在该组件被销毁的时候所触发的事件。具体效果如下。
点击我查看在线Demo
部分参数变化,组件渲染
上面部分已近讲述了一个函数组件在刚创建和被销毁的时候都会对外暴露一个事件钩子,业务开发者可以在提供的钩子事件中去处理需要处理的业务。
在平时一些比较复杂的业务开发场景中可能会遇到一个函数组件,有一部分变量变化的时候需要执行某些特定操作,但另一些变量变化的时候不需要执行某些特定的操作,简而言之就是希望在同一个函数组件中对不同的变量进行区别对待。
比如在一个函数组件中具有 age 和count 两个变量,但是只有在age变化的时候会触发一个弹框,但是 count变化的时候则不会触发这个弹框,只会把新增之后的数字展现在页面上
要实现这个效果实际上就是使用了 useEffect的第二个参数,第二个参数是一个数组,用于登记当该函数组件中的哪些变量变化时候会再次触发useEffect中第一个函数参数,这里之所以说是再次是因为在该组件第一次被创建时候是一定会执行一次的。
效果如下:
点击我查看在线Demo
总结
- Effect Hook 可以实现类组件中的生命周期的功能
- uesEffect 第一个参数接受一个函数,该函数会在初始化该函数组件时被调用
- useEffect 第一个参数中的函数可以return 另一个函数,该函数会在该函数组件被销毁的时候调用,类似class组件中的 componentWillUnmount 作用
- useEffect 第二个参数是一个数组,该数据登记那些状态变量更新的时候,第一个函数参数会再次被调用,类似类组件中的 shouldComponentUpdate功能
- useEffect第二个参数可不传,此时该函数组件中所有状态变量变化时,第一个函数参数都会被调用
- useEffect第二个参数可传一个空数组 [ ],此时该effect中的内容只有在该函数组件第一次新建和最后一次销毁的时候被执行
- useState 和useEffect 可以完全代替一个class组件来实现相同的业务功能
当然使用React Hook 也是有一些规则
8. 只在顶层中使用Hook,并且不要在循环、遍历、嵌套函数中使用Hook
9. 只在React 函数(React函数组件和React自定义Hook)中使用React Hook,不要在普通函数中使用Hook
至此通过上述我们知道可以使用 State Hook和 Effect Hook来实现类似class组件中的状态和生命周期的作用。而使用这两个钩子一般也足以应付我们日常中的大部分常规需求了。
对于其他的功能,比如实现组件传值,和状态统一管理,也是有其对应的Hook来实现。后面会再和大家分享。
维李设论: link的方式其实也是pnpm和lerna快速的一个原因,所不同的是不同包管理器的不同版本对link的优化也不尽相同,所以如果使用link需要保证两侧的包管理器及版本一致,即:使用yarn 2.x就都使用yarn 2.x,使用npm 7.x就都使用npm 7.x
学习Java的唐唐: 问下大佬,ecosystem.config.js,里面是什么内容
lsj980Ya: 我这边遇到找不到node命令,什么都配置好了
问白: 可以检查看看对应的node插件有没有安装
jianghx1024: 安装了在全局配置nodejs的时候版本没有下拉选择框时咋回事