首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么useEffect没有被触发?

为什么useEffect没有被触发?
EN

Stack Overflow用户
提问于 2020-11-03 21:06:24
回答 2查看 100关注 0票数 4

我有一个功能组件,它应该是一个运行的时钟:

代码语言:javascript
运行
复制
import React,{useState,useEffect} from 'react';
import 'materialize-css/dist/css/materialize.min.css';
import { parseTime } from '../../Utils/utils'

const MainClock = (props) => {
    const [timeString, setTimeString] = useState(parseTime(new Date(), true));
    function tick(){
        console.log("TICK:" + timeString)
        setTimeString(parseTime(new Date(), true));
    };

    useEffect(()=>{console.log("rendered!");setTimeout(tick,500);},[timeString]);
    return (
        <div>
            <h5 className="center-align mainclock">{timeString}</h5>
        </div>        
    );
}
 
export default MainClock;

但由于某些原因,它只渲染了两次,控制台输出为:

代码语言:javascript
运行
复制
rendered!
TICK:14:56:21
rendered!
TICK:14:56:22

为什么useeffect在第二次渲染后没有被调用?

欢迎任何帮助!

编辑:如果有帮助,这是parseTime

代码语言:javascript
运行
复制
const parseTime = (timeDate, withSeconds=false) =>{
    let time = timeDate.getHours()<10 ? `0${timeDate.getHours()}`:`${timeDate.getHours()}`;
    time+=":";
    time+= timeDate.getMinutes()<10 ? `0${timeDate.getMinutes()}`:`${timeDate.getMinutes()}`;
    if(withSeconds){
        time+=":";
        time+=timeDate.getSeconds()<10 ? `0${timeDate.getSeconds()}`:`${timeDate.getSeconds()}`;
    }
    return time;
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-11-03 21:13:11

问题是使用setTimeout和使用低延迟,即用于超时的500ms。如果记录parseTime的返回值,您将注意到在两次调用之间,它返回相同的时间字符串,因此状态永远不会更新,从而导致组件永远不会重新呈现,因此useEffect永远不会再次执行以设置另一个setTimeout

解决方案

增加超时延迟或检查parseTime函数的返回值,如果与状态中的返回值相同,则再次调用此函数。

此外,在这里使用setInterval比使用setTimeout更合适,因为setInterval只需要调用一次,它将重复调用tick函数,直到取消间隔。如果使用setTimeout,则需要一次又一次地调用setTimeout来安排新的tick函数调用。

票数 4
EN

Stack Overflow用户

发布于 2020-11-03 21:54:30

如上所述,这是短setTimeout计时值- 500ms的问题。要使其正常工作,您需要使用setInterval

代码语言:javascript
运行
复制
const MainClock = (props) => {
    const [timeString, setTimeString] = useState(parseTime(new Date(), true));
    function tick(){
        console.log("TICK:" + timeString)
        setTimeString(parseTime(new Date(), true));
    };

    useEffect(() => {
      setInterval(tick, 500);
    }, []);
    useEffect(()=>{console.log("rendered!");},[timeString]);
    return (
        <div>
            <h5 className="center-align mainclock">{timeString}</h5>
        </div>        
    );
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64663425

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档