难度级别:中级及以上 提问概率:65%
很多前端开发人员习惯了Vue或者React的组件式开发,熟知组件的周期过程包含初始化、挂载完成、修改和卸载等阶段。但是当使用Hooks做业务开发的时候,看见一个个useEffect函数,却显得有些迷茫,因为在useEffect中,不需要定义那些生命周期的钩子函数了,那么怎么知道组件走到哪一个周期了呢?我们一起来看一下。
useEffect其实可以看做是componentDidMount、componentDidUpdate和componentWillUnmount这3个周期的结合展现,也就是说在useEffect函数内,可以通过一定的控制达到这3个生命周期的结合效果。useEffect接收两个参数,第一个参数是一个函数,重点在于第二个参数。第二个参数是非必填的,它是一个数组,主要通过第二个参数来控制useEffect的阶段。
例如要实现componentDidMount,我们知道componentDidMount是在组件初始化阶段才会被调用,在组件后续的更新和卸载阶段并不会执行,可以通过给useEffect函数的第二个参数传递空数组的方式模拟componentDidMount阶段。代码如下
React代码:
<script>
import { useEffect } from 'react';
function App() {
// 模拟componentDidMount阶段
useEffect(() => {
console.log('初始化调用,可在此发送Ajax请求');
}, [])
}
export default App;
</script>
例如要实现componentDidUpdate,也就是说需要通过useEffect监听数据变化,然后执行一定的业务逻辑,代码如下
React代码:
<script>
import { useState, useEffect } from 'react';
function App() {
let [num, setNum] = useState(0);
let numCount = setTimeout(() => {
num++;
setNum(num);
}, 1000)
// 模拟componentDidUpdate阶段
useEffect(() => {
console.log(num);
}, [num])
}
export default App;
</script>
例如要实现componentWillUnmount,可以通过在useEffect中返回函数的方式,模拟即将卸载的阶段,同时做一些取消监听事件或是停止定时任务的操作。代码如下
React代码:
<script>
import { useState, useEffect } from 'react';
function App() {
let [num, setNum] = useState(0);
let numCount = setTimeout(() => {
num++;
setNum(num);
console.log(num);
}, 1000)
// 模拟componentWillUnmount阶段
useEffect(() => {
return ()=> {
console.log('组件即将卸载');
window.clearTimeout(numCount);
numCount = null;
}
}, [])
}
export default App;
</script>
既然开发者们那么推崇Hooks编程,或者说是函数式编程,那么与类组件编程相比,函数式编程有哪些优势呢?
首先从入门上来说,可以使初学者更方便更习惯的使用Javascript语言进行编写,有效降低入门门槛;从使用上来说,函数式使得组件更容易被复用,它简洁易维护的特点,使得函数式组件成为编写React组件的首选;在性能方面,引入了useMemo和useCallback等hook,有效帮助开发者们更好的进行优化;在测试方面,使用Hooks编写的组件,更关注输入和输出,非常有利于开发人员做单元测试。
刷题思考
很多面试官会习惯性的先问一句:你用过Hooks吗?这个时候如果求职者意识不到这句话只是一个引子,就大错特错了。这个时候,求职者应该反守为攻,将自己提前整理好的Hooks用法、如何模拟生命周期、Hooks在性能优化方面的使用以及函数式编程的优点描述出来。
相信求职者如果把这些知识点描述出来以后,面试官知道你是有备而来,在这块的问题也就所剩无几了。
类似考点
在掌握了本小节的知识点后,求职者还需要进阶性的提前整理以下这些问题,例如你知道React Hooks还有哪些常用方法吗?例如请你说一说,useEffect的第二个数组参数,空数组和有值数组之间有哪些区别吗?例如你能说一说,useEffect和useLayoutEffect之间有什么区别吗?