我正在尝试在页面加载时加载引导模式,除非按下取消按钮。该功能应该起作用的方式是,一旦页面加载,等待2秒钟并显示模式,除非按下了取消按钮,否则该模式将不显示,但是无论是否按下了取消按钮,该模式都会显示,< / p>
const Call = ({ t, i18n }) => {
const [modalShow, setModalShow] = useState(false);
const [cancelCall, setCancelCall] = useState(false);
useEffect(() => {
if (cancelCall) {
return;
} else {
setTimeout(() => {
setModalShow(true);
}, 2000);
}
}, [setModalShow, cancelCall]);
const handleCancelCall = e => {
setCancelCall(true);
console.log("cancel call pressed!");
};
return (
<Fragment>
<CallModal show={modalShow} onHide={() => setModalShow(false)} />
<button
type="button"
className="ml-4 btn btn-light"
onClick={e => handleCancelCall()}
>
Cancel
</button>
</Fragment>
);
};
任何帮助将不胜感激。
答案 0 :(得分:1)
这是因为在页面加载时,您的cancelCall
始终为false,因此您将注册一个超时事件。
发布该用户单击该按钮,但还需要删除已注册事件的信息。试试:
const Call = ({ t, i18n }) => {
const [modalShow, setModalShow] = useState(false);
const [cancelCall, setCancelCall] = useState(false);
// Save the timer id in state
const [timer, setTimer] = useState(null);
useEffect(() => {
if (cancelCall) {
return;
} else {
const timer = setTimeout(() => {
setModalShow(true);
}, 2000);
setTimer(timer)
}
}, [setModalShow, cancelCall]);
const handleCancelCall = e => {
setCancelCall(true);
// On cancel, check if timer is not null. If not clear the timer from queue
!!timer && window.clearTimeout(timer);
setTimer(null)
console.log("cancel call pressed!");
};
return (
<Fragment>
<CallModal show={modalShow} onHide={() => setModalShow(false)} />
<button
type="button"
className="ml-4 btn btn-light"
onClick={e => handleCancelCall()}
>
Cancel
</button>
</Fragment>
);
};
答案 1 :(得分:1)
尽管@Rajesh的答案有效,但它导致2次不必要的重新渲染(调用setTimer
)。我建议您直接使用ref
来跟踪计时器
const [modalShow, setModalShow] = useState(false);
const modalTimer = useRef(null);
useEffect(() => {
// the if (cancelCall) part in here was pointless
// because initial state is always false
modalTimer.current = setTimeout(() => setModalShow(true), 2000);
}, []);
const handleCancelCall = e => {
// on cancel, simply clear the timer
modalTimer.current && clearTimeout(modalTimer.current);
};
以上内容还删除了一些多余的代码和状态。