Home > Software engineering >  How can I invoke same function multiple times on button click in react
How can I invoke same function multiple times on button click in react

Time:10-21

I have a form where users can use a DateTimepicker to select a starting time and date or click on a "use current time" button to get the starting time and date. Also, for the ending date and time, the users can use DateTimepicker for selection or use one of 3 buttons labeled 30 minutes, 1 hour and 4 hours which adds 30 minutes, 1 hr and 4 hrs to the starting time respectively.

But when I click on any of this button, it only works once. Then I have to click on another before I see any change again.

My Aim

I want it such that, when I click on 30 minutes, it adds 30 minutes to the starting time, if I click on it again, it adds another 30 minutes. And, if I then click on the 1 hour, it adds 1 hr to the time I have already.

This is my code shown below. How can I achieve my aim?

...
<div className={`time-buttons-container ${!showTime ? "hide-buttons" : ""}`}>
    <button className={`time-buttons`} onClick={() => addTime(1, 30)}>   30 mins</button>
    <button className={`time-buttons`} onClick={() => addTime(1, 60)}>  1 hour</button>
    <button className={`time-buttons`} onClick={() => addTime(4, 60)}>  4 hours</button>
</div>
...

The adding function

const addTime = (hours, minutes) => {
        let dateVar;
        let timeVar;
        if(!startDate ){
            dateVar = createDateAsUTC()
        } else {
            dateVar = startDate
        }
        if(!startTime ){
            timeVar = createDateAsUTC();
        } else {
            timeVar = startTime
        }

        const getDate = new Date(dateVar)
        const getHours = new Date(timeVar).getHours()
        const getMinutes = new Date(timeVar).getMinutes()
        const dateTime = new Date(getDate).setHours(getHours, getMinutes);

        const thirtyMinutes = hours * minutes * 60 * 1000;
        const futureTime = new Date().setTime(dateTime   thirtyMinutes);
        const newTime = new Date(futureTime)

        setStartDate(dateVar)
        setStartTime(timeVar)
        setEndDate(newTime);
        setEndTime(newTime);
    };

My states

    const [startDate, setStartDate] = useState("");
    const [endDate, setEndDate] = useState("");
    const [showTime, setTime] = useState(false);
    const [startTime, setStartTime] = useState("");
    const [endTime, setEndTime] = useState("");

Thanks for your responses.

CodePudding user response:

You can make better use of Javascript's Date API to simplify the addTime function. You also don't need to store date and time in separate variables since a JS Date object tracks both date and time.

This function will add x number of minutes to the current endDate and set that as the new state. I would set the startDate in a different function.

const [endDate, setEndDate] = useState(null);

const addTime = (hours, minutes) => {
  const newEndDate = endDate ? new Date(endDate) : new Date();
  const currentMinutes = newEndDate.getUTCMinutes();
  
  // setUTCMinutes will roll over values over 60 into hours
  newEndDate.setUTCMinutes(hours * minutes   currentMinutes);

  setStartTime(newEndDate); 
};

CodePudding user response:

Based on the inputs given above, I refactored my code to pass in only minutes to the addTime function.

Then I conditionally update state. See below:

const addTime = (minutes) => {
    let dateVar;
    let timeVar;
    if (!startDate) {
      dateVar = createDateAsUTC();
    } else {
      dateVar = startDate;
    }
    if (!startTime) {
      timeVar = createDateAsUTC();
    } else {
      timeVar = startTime;
    }

    //const endTime = new Date(timeVar.getTime()   (minutes * 60000));
    setStartDate(dateVar);
    setStartTime(timeVar);
    //setEndDate(dateVar);

    if (endTime) {
      setEndTime((prevTime) => {
        return new Date(prevTime.getTime()   minutes * 60000);
      });
      setEndDate((prevDate) => {
        return new Date(prevDate.getTime()   minutes * 60000);
      });
    } else {
        setEndTime(new Date(timeVar.getTime()   (minutes * 60000)));
        setEndDate(new Date(dateVar.getTime()   (minutes * 60000)));
    }
}
  • Related