Tengo este enlace personalizado useCountDown que es básicamente un temporizador de cuenta regresiva y lo estoy usando en el componente InputInvestment . Uso un envío para enviar el conteo a la tienda y capturar estos datos a través de useSelector y mi resultado es algo así como:
temporizadorCuenta regresiva 10
volver a hacer
temporizadorCuenta atrás 9
volver a hacer
temporizadorCuenta atrás 8
volver a hacer
temporizadorCuenta atrás 7
volver a hacer
temporizadorCuenta atrás 6
volver a hacer
.
.
.
.
Como puede ver, tengo un problema de renderizado y me gustaría obtener estos datos de cuenta regresiva sin volver a renderizar mi componente InputInvestment.
usarCuenta atrás
import { useEffect, useState } from 'react'; import { useSelector } from 'react-redux'; import { setTimerCountdown } from 'redux/actions/expirationTimer'; import { useDispatch } from 'react-redux'; const useCountDown = (start) => { const dispatch = useDispatch(); const timerCountdown = useSelector(state => state.expirationTimer.countdown); const [counter, setCounter] = useState(start); useEffect(() => { if (counter === 0) { return; } setTimeout(() => { setCounter(counter - 1); }, 1000); }, [counter]); dispatch(setTimerCountdown(counter)); return timerCountdown; }; export default useCountDown;Componente InputInvestment
const InputInvestment = ({ history, offering, userState, attemptToInvest }) => { const expirationTimer = { EXPIRATION_TIMEOUT: 15, EXPIRATION_INTERVAL: 1000, }; useCountdown(expirationTimer.EXPIRATION_TIMEOUT); const timerCountdown = useSelector(state => state.expirationTimer.countdown); // eslint-disable-next-line no-console console.log('rerender') // eslint-disable-next-line no-console console.log('timerCountdown', timerCountdown) if (timerCountdown === 0) { const title = 'Investment request expired'; const errorMessage = [ <> Your investment request has expired due to inactivity. If you would like to invest in {offering.title}, please{' '} <Link to={`/offering/${offering.urlHash}/`}>click here</Link> to start a new investment. </>, ]; return ( <NotificationWrapper> <NotificationMessage title={title} textList={errorMessage} /> </NotificationWrapper> ); } else { ... };Mi solución a este problema fue poner esta lógica de temporizador de cuenta regresiva directamente en la acción y enviar esto en el componente InputInvestment y también creé un valor booleano en lugar de recuperar un número en el componente, por lo que ahora la representación ya no sucede :)
Acción
export const setTimerRunning = (expirationTime) => dispatch => { let counter = expirationTime; const interval = setInterval(() => { counter--; // eslint-disable-next-line no-console console.log('setTimerRunning',counter) if (counter < 0 ) { clearInterval(interval); } if(counter === 0){ dispatch({ type: SET_TIMER_EXPIRED }); } }, 1000); };reductor
import update from 'immutability-helper'; import * as actions from 'redux/actions/expirationTimer'; export const initialState = { expired: false, }; const expirationTimer = (state = initialState, action) => { switch (action.type) { case actions.SET_TIMER_EXPIRED: { return update(state, { expired: { $set: true, }, }); } default: return state; } }; export default expirationTimer;