Javascript onClick内的反应状态引用错误-可能存在关闭问题?
这里是我拥有的React组件的精简版本。它是一个带有介绍动画的主屏幕,在超时后将自动结束并淡出,但用户也可以跳过Javascript onClick内的反应状态引用错误-可能存在关闭问题?,javascript,reactjs,react-hooks,Javascript,Reactjs,React Hooks,这里是我拥有的React组件的精简版本。它是一个带有介绍动画的主屏幕,在超时后将自动结束并淡出,但用户也可以跳过 import React, { useEffect, useState } from "react"; export function Home() { const [introEnded, setIntroEnded] = useState(false); // function to end intro animation function endIntro()
import React, { useEffect, useState } from "react";
export function Home() {
const [introEnded, setIntroEnded] = useState(false);
// function to end intro animation
function endIntro() {
console.log(introEnded); // THIS IS WRONG THE SECOND TIME FUNCTION IS CALLED
if (!introEnded) {
setIntroEnded(true);
// do various other stuff
}
// do various other stuff
}
// if user does not interact, intro ends automatically
useEffect(() => {
setTimeout(function() {
endIntro();
}, 4000);
}, []);
// user can skip intro on click
return (
<div>
<div onClick={endIntro}>Skip Intro</div>
</div>
);
}
import React,{useffect,useState}来自“React”;
导出函数Home(){
常量[introEnded,setIntroEnded]=useState(false);
//结束介绍动画的函数
函数endIntro(){
console.log(introend);//第二次调用函数时,这是错误的
如果(!内向){
设置为内向(真);
//做各种其他的事情
}
//做各种其他的事情
}
//如果用户不进行交互,介绍将自动结束
useffect(()=>{
setTimeout(函数(){
endIntro();
}, 4000);
}, []);
//用户可以单击跳过介绍
返回(
跳过简介
);
}
问题是,在用户跳过后,当超时开始并再次调用endIntro()
时,introend
状态是错误的。第一次调用endIntro()
时,我已将其明确设置为true,但第二次调用endIntro()
时似乎引用了旧的状态
研究告诉我这是一个封闭的问题,但我无法找到解决办法
发生了什么事,我该怎么解决?谢谢 是的,这是一个Javascript关闭问题。调用useEffect时,变量introEnded的值为false,这是无法避免的。为了实现这个目标,我们需要编写一些如下的手动代码
导出函数Home(){
常量[introEnded,setIntroEnded]=useState(false);
const[appeased,setappeased]=useState(0);
const start=React.useMoom(()=>{
返回新日期().getTime();
}, []);
//结束介绍动画的函数
const endIntro=React.useCallback(()=>{
console.log(introend);//第二次调用函数时,这是错误的
如果(!内向){
设置为内向(真);
//做各种其他的事情
}
//做各种其他的事情
},[内向];
//如果用户不进行交互,介绍将自动结束
useffect(()=>{
//控制台日志(已用);
设timerId=-1
如果(4000>已过){
timerId=setTimeout(函数(){
endIntro();
},4000-年;
}
return()=>{
setAppeased(新日期().getTime()-start);
如果(timerId>0)clearTimeout(timerId);
};
},[经过,结束,开始];
//用户可以单击跳过介绍
返回(
跳过简介
);
}
您不必在useffect
中调用整个函数,只需更新您的简介状态即可
此外,您可能需要返回一个清理函数,该函数将在useffect
结束时将状态重置为false
,该函数将模拟组件willunmount()
。在这里阅读更多
const-App=()=>{
常量[introEnded,setIntroEnded]=React.useState(false);
//结束介绍动画的函数
函数endIntro(){
setIntroEnded(真)
//做你的其他事情
console.log('跳过')
}
//如果用户不进行交互,介绍将自动结束
React.useffect(()=>{
//在x秒后改变状态
setTimeout(函数(){
setIntroEnded(真)
}, 4000);
//清理并将其设置回false
return()=>setIntroEnded(false)
}, []);
返回(
跳过简介
{!简介?你的简介…这将在4秒后结束..:简介已结束..}
)
}
ReactDOM.render(,document.getElementById('root'))代码>
您必须在代码中实现的一些技巧:
主组件销毁时,通过返回的id清除超时
改为使用setState回调,并在将函数调用为setTimeout回调之前进行检查
import React,{useffect,useState}来自“React”;
导出函数Home(){
常量[introEnded,setIntroEnded]=useState(false);
//结束介绍动画的函数
函数endIntro(){
console.log(introend);//第二次调用函数时,这是错误的
setIntroEnded(()=>true);
//做各种其他的事情
//做各种其他的事情
}
//如果用户不进行交互,介绍将自动结束
useffect(()=>{
const setTimeoutId=setTimeout(()=>{
如果(!内向){
endIntro();
}
}, 4000);
return()=>{
clearTimeout(setTimeoutId);
};
}, []);
//用户可以单击跳过介绍
返回(
endIntro()}>跳过介绍
);
}
因此,我将得出结论,当应用程序加载时,您调用动画,以便它现在开始动画用户单击skip,但动画仍然有效,因此您需要取消正在进行的动画,该动画将在4秒内结束。这是您的问题吗?这是您正在寻找的吗?