2 votes

comment concevoir un réducteur qui doit changer chaque seconde ?

J'essaie de faire une application de minuterie, chaque minuterie a un temps qui diminue jusqu'à ce qu'elle se termine (arrive à 0) et un son est joué : my timers

l'état initial de chaque temporisateur possède une propriété, nommée passing :

const INITIAL_STATE = {
  ... 
  passing: false 
};

pour chaque minuterie, si son passing est vrai, chaque seconde où j'appelle pass action pour décrémenter son temps :

componentDidUpdate(){
  if(timer.passing){ 
     this.pass(timer.id) 
  } 
}

pass = (id)=>{ 
  setInterval(()=>{
    this.props.pass(id)
  }, 1000)
};

mon reducer :

case PASS:
  let newTimers = [];
  state.timers.map(timer=>{
    if(timer.id === action.payload){
      const {hours, minutes, seconds} = timer.time;
      if(hours < 1 && minutes < 1 && seconds < 1){
         timer.passing = false;
         timer.alarm = true;
      }else if(timer.time.seconds === 0){
         if(timer.time.minutes === 0){
            timer.time.hours--;
            timer.time.minutes = 59;
            timer.time.seconds = 59;
         }else{
            timer.time.minutes--;
            timer.time.seconds = 59;
         }
      }else{
         timer.time.seconds--;
      }
    }
    newTimers.push(timer);
  });
  return {...state, timers: newTimers};

cette approche est correcte lorsque je ne lance qu'une seule minuterie, mais dès que je lance plusieurs minuteries, une seule d'entre elles fonctionne, parce que de multiples pass actions sont appelés en même temps.

Alors comment puis-je faire en sorte que mon réducteur se mette à jour lui-même, sans que je doive appeler des actions à chaque seconde ?

rappelez-vous qu'il n'y a pas d'heure cible spécifique, comme 16 heures, etc. l'utilisateur peut appuyer sur le bouton stop et maintenir le minuteur pendant quelques heures, puis appuyer sur le bouton start(continue). Il n'est donc pas possible d'obtenir l'heure actuelle et de calculer le temps restant jusqu'à l'heure cible. temps restant jusqu'à l'heure cible ne peut pas être fait.

1voto

a_m_dev Points 1115

Vous n'avez pas besoin de créer un reducer pour changer toutes les secondes, vous avez besoin de dispatcher l'action appropriée à l'intérieur de l'intervalle dans votre composant.

1voto

Deniz Aslan Points 407

Il me semble qu'un des problèmes est que vous appelez this.pass sur componentDidUpdate qui se répercutera sur de nombreux setInterval des mises à jour et perturber les minuteries. Essayez de le faire sur componentDidMount à la place de la minuterie passing y id provenant de props . forceUpdate semble également nécessaire lorsqu'on travaille avec des intervalles.

  componentDidMount() {
    setInterval(() => {
      this.props.pass(this.props.id);
      this.forceUpdate(); // seems like you need this in setInterval
    }, 1000);
  }

J'ai créé un CodeSandbox avec un exemple fonctionnel de base de votre cas d'utilisation.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X