反复玩弄To-Do-List之定时器参数传入fn与fn()的区别

54 阅读2分钟

记录学习过程中的小波折,跪求各位大佬路过指出不足之处

阅读此篇文章需要做出以下前提工作:
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,运行一下试试:

屏幕录制2023-10-22 下午9.15.14.gif

emmmm,跑是跑起来了,就是有个小瑕疵哈

不慌!检查代码!

WechatIMG1084.png

哦~原来是这里,把tick()改成tick

okok,跑起来了!丝滑得很啊朋友们~

那就要问了,怎么()一去就好了?

首先看问题出在哪里,立马定位到setInterval

定时器定义

image.png

setInterval与setTimeout用法是一致的。

哦~原来如此,这里写函数名就行了哈

但是为什么这里写函数名就行了啊???

哦~原来如此~写一个简单示例

image.png 此时控制台输出

image.png
很明显,当fn()作为参数传入定时器时,只执行了一次,而且观察控制台输出发现是立马执行了,并未等待一秒后输出。

由此可以得到结论:

当使用函数名作为参数传入定时器时,传递的是只是函数的定义并不会立即执行。

当传入fn()作为参数时,fn()立马执行,并且只执行了一次,因为当定时器根据tick()作为函数名去寻找函数时,是必然查找不到的。

而在本例中,tick()作为同步任务立马执行了,于是触发useeffect依赖项的改变,hook一刷新,tick()又立马执行......如此反复无限刷新,进而导致报错产生。

如此,再不敢忘,定时器,只传名字不加()!