Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

135
Vistas
Why does my counter value increase before it starts to decrease on click - reactjs

I'm making an attendance form where teachers can mark who's absent and not and check who was absent the previous days. I have the current date at the top and button which allows it to change the date forward and back. However, when I try to increase the value it works fine, but then when I decrease it increases by one first and then decreases after every click.

 const [date, setDate] = useState()

  var today = new Date();
    var dd = parseInt(String(today.getDate()).padStart(2, '0'));
    var mm = String(today.getMonth() + 1).padStart(2, '0'); //January is 0!
    var yyyy = today.getFullYear(); 
    
    today = dd + '/' + mm + '/' + yyyy;
    useEffect(() => {
      setDate(today)

    }, [])

const[newDay, setNewDay] = useState(dd)
  
  const changeToTomorrow = () => {
    setNewDay(newDay + 1)
    setDate(newDay + '/' + mm + '/' + yyyy)
    console.log(date)
  }

  const changeToYesterday = () => {
    setNewDay(newDay - 1)
    setDate(newDay + '/' + mm + '/' + yyyy)
  }


    return (
        <div className="attendance-today-container">
          <h1>Daily attendance</h1>
          <div className='change-date-container'>
            <div className='change-date'>
              <i class="fas fa-arrow-left" onClick={changeToYesterday}></i>
              <p>{date}</p>
              <i class="fas fa-arrow-right" onClick={changeToTomorrow}></i>
            </div>
          </div>
about 4 years ago · Juan Pablo Isaza
3 Respuestas
Responde la pregunta

0

When you update a state using setNewDay(newDay + 1) the newDay variable is not immediately updated. So when you do setDate(newDay + '/' + mm + '/' + yyyy) you still use the old value of newDay to update date.

Example:

You have initial state newDay = 10 date = 10/xx/xx, then you click on increase button and the next code is executed. setNewDay(10 + 1) setDate(10 + '/' + mm + '/' + yyyy)

After react renders component with a new state you got newDay = 11 date = 10/xx/xx on the next click to increase you would get setNewDay(11 + 1) setDate(11 + '/' + mm + '/' + yyyy)

So you date variable update is always one step behind.

How to fix

You should do something like

let nextDay = newDay + 1
setNewDay(nextDay)
setDate(nextDay + '/' + mm + '/' + yyyy)

in both functions

about 4 years ago · Juan Pablo Isaza Denunciar

0

You are trying to set two states in a row while those are asynchronous and might not give you the updated value of newDay by the time you set date.

A fast fix can be as follows (I rearrange the code a bit with spacing):

import {useState, useEffect} from "react";

export default function SomeComponent() {
  
  const [date, setDate] = useState()

  var today = new Date();
  var dd = parseInt(String(today.getDate()).padStart(2, '0'));
  var mm = String(today.getMonth() + 1).padStart(2, '0'); //January is 0!
  var yyyy = today.getFullYear(); 
  
  today = dd + '/' + mm + '/' + yyyy;
  useEffect(() => {
    setDate(today)

  }, [])

  const[newDay, setNewDay] = useState(dd)

  const changeToTomorrow = () => {
    const updateDay = newDay + 1
    setNewDay(updateDay)
    setDate(updateDay + '/' + mm + '/' + yyyy)
    console.log(date)
  }

  const changeToYesterday = () => {
    const updateDay = newDay - 1
    setNewDay(updateDay)
    setDate(updateDay + '/' + mm + '/' + yyyy)
  }


  return (
      <div className="attendance-today-container">
        <h1>Daily attendance</h1>
        <div className='change-date-container'>
          <div className='change-date'>
            <i class="fas fa-arrow-left" onClick={changeToYesterday}></i>
            <p>{date}</p>
            <i class="fas fa-arrow-right" onClick={changeToTomorrow}></i>
          </div>
        </div>
      </div>
  );
}

Calculate the updated date first in a new variable and then set it to both states:

  const changeToTomorrow = () => {
    const updateDay = newDay + 1
    setNewDay(updateDay)
    setDate(updateDay + '/' + mm + '/' + yyyy)
    console.log(date)
  }

  const changeToYesterday = () => {
    const updateDay = newDay - 1
    setNewDay(updateDay)
    setDate(updateDay + '/' + mm + '/' + yyyy)
  }
about 4 years ago · Juan Pablo Isaza Denunciar

0

May I suggest a different approach, as well as a different organization of the code?

const { useState, useEffect, useCallback } = React;

// utility function (not part of the component)
function formatDate(date, format = 'dd/mm/yyyy') {
  const addLeadingZero = num => {
    return num < 10 ? `0${num}` : num.toString();
  }

  const dd = addLeadingZero(date.getDate());
  const mm = addLeadingZero(date.getMonth() + 1);
  const yyyy = date.getFullYear().toString();

  return format.replace('dd', dd).replace('mm', mm).replace('yyyy', yyyy);
}

// This constant is not strictly necessary but I think it makes the code more readable
const ONE_DAY_MSEC = 86400000;

// Component
const MyComponent = () => {
  const [date, setDate] = useState(new Date()); // date as a date
  const [dispDate, setDispDate] = useState(formatDate(new Date())); // date as a formatted string
  
  useEffect(() => {
    setDispDate(formatDate(date))
  }, [date, setDispDate]);
  
  const handleNextDayClick = useCallback(() => {
    setDate((current) => new Date(current.getTime() + ONE_DAY_MSEC))
  }, [setDate]);
  
  const handlePrevDayClick = useCallback(() => {
    setDate((current) => new Date(current.getTime() - ONE_DAY_MSEC))
  }, [setDate]);
  
  return (
    <div>
      <div>Date: {dispDate}</div>
      <button onClick={handlePrevDayClick}>prev day</button>
      <button onClick={handleNextDayClick}>next day</button>
    </div>
  );
}

ReactDOM.render(<MyComponent />, document.getElementById('App'));
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>

<div id="App" />

about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda