记录学习过程中的小波折,跪求各位大佬路过指出不足之处
阅读此篇文章需要做出以下前提工作:
1、具备基础的js知识
2、了解useeffect
正文:
打算写一个显示当前时间的组件放到todolist的标题处,这还不简单,看我手起刀落:
import { useEffect, useState } from "react";
const Time = () =>{
const [date,setDate] = useState(new Date());
useEffect(()=>{
function tick(){
setDate(new Date())
}
const timeId = setInterval(tick(),1000);
return ()=> clearInterval(timeId);
},[date])
return(
<div>Time:{date.toLocaleTimeString()}</div>
)
}
export default Time;
ok,运行一下试试:
emmmm,跑是跑起来了,就是有个小瑕疵哈
不慌!检查代码!
哦~原来是这里,把tick()改成tick
okok,跑起来了!丝滑得很啊朋友们~
那就要问了,怎么()一去就好了?
首先看问题出在哪里,立马定位到setInterval
定时器定义
setInterval与setTimeout用法是一致的。
哦~原来如此,这里写函数名就行了哈
但是为什么这里写函数名就行了啊???
哦~原来如此~写一个简单示例
此时控制台输出
很明显,当fn()作为参数传入定时器时,只执行了一次,而且观察控制台输出发现是立马执行了,并未等待一秒后输出。
由此可以得到结论:
当使用函数名作为参数传入定时器时,传递的是只是函数的定义并不会立即执行。
当传入fn()作为参数时,fn()立马执行,并且只执行了一次,因为当定时器根据tick()作为函数名去寻找函数时,是必然查找不到的。
而在本例中,tick()作为同步任务立马执行了,于是触发useeffect依赖项的改变,hook一刷新,tick()又立马执行......如此反复无限刷新,进而导致报错产生。
如此,再不敢忘,定时器,只传名字不加()!