Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/418.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 为什么未触发useEffect?_Javascript_Reactjs_Use Effect_React Component_Use State - Fatal编程技术网

Javascript 为什么未触发useEffect?

Javascript 为什么未触发useEffect?,javascript,reactjs,use-effect,react-component,use-state,Javascript,Reactjs,Use Effect,React Component,Use State,我有一个功能组件,应该是一个运行的时钟: 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] = useSt

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

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;
为什么在第二次渲染后不调用useeffect

欢迎任何帮助

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

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;
}
const parseTime=(timeDate,withSeconds=false)=>{

let time=timeDate.getHours()问题在于使用
setTimeout
和使用低延迟,即
500ms
作为超时。如果记录
parseTime
的返回值,您会注意到在两次调用之间,它返回相同的时间字符串,因此状态从不更新,导致组件从不重新渲染,因此
useffect
n是否再次执行以设置另一个
setTimeout

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


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

如上所述,这是短
设置超时
定时值的问题-
500ms
。 要使其工作,您需要使用
setInterval

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>        
    );
}
const MainClock=(道具)=>{
const[timeString,setTimeString]=useState(parseTime(new Date(),true));
函数tick(){
log(“勾选:+timeString”)
setTimeString(parseTime(new Date(),true));
};
useffect(()=>{
设定间隔(刻度,500);
}, []);
useffect(()=>{console.log(“rendered!”);}[timeString]);
返回(
{timeString}
);
}

是否在每次渲染后使用
setInterval
创建多个堆叠间隔?如果tick正在更新依赖项数组中已有的变量,为什么我需要向依赖项数组添加tick?我认为setTimeout而不是setInterval是正确的,因为setInterval总是重复调用tick函数。@MaorMagori分享了
parseTime
的代码,我将进一步解释问题发生的原因以及如何解决问题,或者在codesandbox上分享一个可复制的示例。@Yousaf补充道。parseTime是问题的原因吗?这里有什么错?我希望“呈现!勾选:…”将连续每500毫秒显示一次。@WilliamWang这就是问题所在。它没有显示“渲染!勾选:…”连续但只有两次。我检查过,它工作正常。是的,没有parseTime,我可以看到连续的printsah,我发现了错误,只需尝试更新设置超时间隔而不是500。您错过了
useEffect
hook的依赖项数组。您只希望
useEffect
只运行一次,还应该使用cleanup fu取消
设置间隔的操作。
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>        
    );
}