如何从react-timer-hook的Timer组件获取当前已用分钟数?
解决Next.js中react-timer-hook计时器在表单提交时获取已用分钟数的问题
方案一:修改Timer组件,在到期回调中传递已用时间
这种方案无需调整组件结构,只需在Timer组件内计算已用时间并传递给handleForm:
更新Timer组件:
接收父组件传入的总时长,计算已用时间后通过回调函数传递给父组件:import { Typography } from '@mui/material'; import { useTimer } from 'react-timer-hook'; export default function Timer({ expiryTimestamp, functionCall, totalDuration }) { const { seconds, minutes, hours } = useTimer({ expiryTimestamp, onExpire: () => { // 计算剩余秒数 const remainingSeconds = hours * 3600 + minutes * 60 + seconds; // 转换为已用分钟数 const usedMinutes = (totalDuration - remainingSeconds) / 60; // 将结果传递给表单处理函数 functionCall(usedMinutes); } }); return ( <Typography variant='h5' fontWeight={'bold'} component={'div'}> <span>{hours < 10 ? '0' + hours : hours}</span>:<span>{minutes < 10 ? '0' + minutes : minutes}</span>:<span>{seconds < 10 ? '0' + seconds : seconds}</span> </Typography> ); }调整Timer组件调用方式:
传入总时长(示例中为3600秒,即1小时):const totalDuration = 3600; const time = new Date(); time.setSeconds(time.getSeconds() + totalDuration); <Timer functionCall={handleForm} expiryTimestamp={time} totalDuration={totalDuration} />修改handleForm函数:
接收传递的已用分钟数并赋值给total_time_taken:async function handleForm(total_time_taken) { const token = Cookies.get('token'); const formData = { user_id: userId, test_id: test_id, total_time_taken: Math.round(total_time_taken), // 可根据需求取整或保留小数 answers: answers }; const data = JSON.stringify(formData); const resp = await axios.post(`answers`, data, { headers: { Authorization: `Bearer ${token}` } }); if (resp.data.success) { router.push('/user/feedback/' + test_id); } }
方案二:状态提升,将计时器状态移到父组件
把useTimer的状态管理放到父组件中,Timer组件仅负责展示时间,让handleForm直接访问计时器数据:
更新父组件逻辑:
引入useTimer并管理状态,直接在handleForm内计算已用时间:import { useTimer } from 'react-timer-hook'; // ... const totalDuration = 3600; const time = new Date(); time.setSeconds(time.getSeconds() + totalDuration); // 父组件初始化计时器 const { seconds, minutes, hours } = useTimer({ expiryTimestamp: time, onExpire: handleForm }); async function handleForm() { const token = Cookies.get('token'); // 计算已用分钟数 const remainingSeconds = hours * 3600 + minutes * 60 + seconds; const total_time_taken = (totalDuration - remainingSeconds) / 60; const formData = { user_id: userId, test_id: test_id, total_time_taken: Math.round(total_time_taken), answers: answers }; const data = JSON.stringify(formData); const resp = await axios.post(`answers`, data, { headers: { Authorization: `Bearer ${token}` } }); if (resp.data.success) { router.push('/user/feedback/' + test_id); } }简化Timer组件:
仅接收父组件传递的时间参数并渲染:import { Typography } from '@mui/material'; export default function Timer({ hours, minutes, seconds }) { return ( <Typography variant='h5' fontWeight={'bold'} component={'div'}> <span>{hours < 10 ? '0' + hours : hours}</span>:<span>{minutes < 10 ? '0' + minutes : minutes}</span>:<span>{seconds < 10 ? '0' + seconds : seconds}</span> </Typography> ); }调用简化后的Timer组件:
<Timer hours={hours} minutes={minutes} seconds={seconds} />
内容的提问来源于stack exchange,提问作者DCodeMania
相关产品推荐
相关产品推荐

