前面根据React的文档介绍,简单调试了useEffect、useCallback两个钩子函数,大致看懂了各自的工作原理。但是并没有涉及到第二个空数组参数,看文档字面意思比较抽象,好像是说如果数组的某个键值发生改变,那么函数本身也会相应再执行一次。总觉得一知半解,还是实际操作一下加深理解。
useEffect函数结构:
useEffect(()=>{},[]);
①修改index.js页面代码,在useEffect函数的第二个参数中加入变量
修改后的index.js页面代码
import Head from 'next/head'
import styles from '../styles/Home.module.css'
import { Footer } from '../components/Footer'
import { Main } from '../components/Main'
import { Header } from '../components/Header'
import { useEffect, useState } from 'react'
export default function Home() {
const[bar, setBar] = useState(1);
const handleclick = (e) =>{
setBar((bar) => bar + 1);
};
console.log(bar);
useEffect(() =>{
console.log(`函数加载开始:${bar}`);
document.body.style.backgroundColor = "lightblue";
return (() =>{
console.log(`return完成:${bar}`);
document.body.style.backgroundColor = "lightgreen";
})
},[bar]);
return (
<div className={styles.container}>
<Head>
<title>Index page</title>
<link rel="icon" href="/favicon.ico" />
</Head>
<Header />
<h1>{bar}</h1>
<button onClick={handleclick}>
累计按钮
</button>
<Main page="index"/>
<Footer />
</div>
)
}
打开index页面控制台,刷新页面,可发现useEffect函数的第一个参数(无名函数)已经加载完成,但return部分没有被执行。
接着点击"累计按钮"2次,根据控制台显示结果可以总结如下:
◆useEffect第二个参数(数组)不为空、并且状态发生改变时,无名函数(也就是useEffect第一个参数)的return区块逻辑就会被执行1次。
◆return区块逻辑会首先被执行,然后再执行return区块外逻辑。
◆return区块逻辑记录的状态是上一次无名函数的执行状态。
②恢复useEffect函数的第二个参数为空数组
刷新index页面,同样可发现useEffect函数的第一个参数(无名函数)已经加载完成,但return部分没有被执行。
接着点击"累计按钮"2次,根据控制台显示结果可以总结如下:
◆useEffect第二个参数(数组)为空时、无名函数(也就是useEffect第一个参数)上一次执行完成后就不再执行。
◆由于return区块逻辑属于无名函数(也就是useEffect第一个参数)中的一部分,无名函数不执行的情况下,当然return区块逻辑也不会被执行。
useCallback函数结构:
useCallback(()=>{},[]);
①修改index.js页面代码,在useCallback函数的第二个参数中加入变量
修改后的index.js页面代码
import Head from 'next/head'
import styles from '../styles/Home.module.css'
import { Footer } from '../components/Footer'
import { Main } from '../components/Main'
import { Header } from '../components/Header'
import { useCallback, useEffect, useState } from 'react'
export default function Home() {
const[bar, setBar] = useState(1);
const handleclick = useCallback((e) =>{
console.log(bar);
setBar( bar + 1);
},[bar]);
useEffect(() =>{
document.body.style.backgroundColor = "lightblue";
return (() =>{
document.body.style.backgroundColor = "lightgreen";
})
},[]);
return (
<div className={styles.container}>
<Head>
<title>Index page</title>
<link rel="icon" href="/favicon.ico" />
</Head>
<Header />
<h1>{bar}</h1>
<button onClick={handleclick}>
累计按钮
</button>
<Main page="index"/>
<Footer />
</div>
)
}
刷新ndex页面
连续点击“累计按钮”,可发现随着点击事件发生,页面和控制台数字不断递增,由此总结如下:
◆useCallback第二个参数(数组)不为空、并且状态发生改变时,无名函数(也就是useCallback第一个参数)会被再次执行。
②恢复useCallback函数的第二个参数为空数组
刷新index页面
接着连续点击"累计按钮",发现页面数字只更新了1次,控制台数字一直没有更新,由此总结如下:
◆useCallback第二个参数(数组)为空时、无名函数(也就是useCallback的第一个参数)上一次执行完成后就不再执行。
以上分别对useEffect、useCallback两个钩子函数的第二个参数的用途,通过实际操作进行了理解。感觉两个函数有共同点也有区别,总结如下:
共同点:两个函数都根据页面状态变化,控制函数是否再次加载,都具备节约资源消耗的优点。
区别:
useEffect函数可在生命周期的开始和结束阶段分别执行相关逻辑
useCallback函数只关注相关逻辑是否重新执行