Home > other >  React Functional Component: onClick handler that updates state is not working
React Functional Component: onClick handler that updates state is not working

Time:10-15

Below is my react functional component. Every 5 seconds I'm updating the time state and showing the time (via showTime()).

I also have a button that, when clicked, will push the current time to the timeList state (which is an array).

However so far I'm getting a bug in the handleClick function. What I want to happen is to push the current time onto the empty timeList array (timeList.push(time)). So timeList would be something like this: ['12:34:57']. However instead timeList is 1 when the button is pushed.

import React, {useState, useEffect} from 'react';

function App() {
  const [time, setTime] = useState(null);
  const [timeList, setTimeList] = useState([]);

  useEffect(
    () => {
      calcTime();
    }, [time]
  );

  const calcTime = () => {
    setTimeout(
      () => {
        const today = new Date();
        const timeNow = today.getHours()   ':'   today.getMinutes()   ':'   today.getSeconds();
        setTime(timeNow);
      }, 5000
    );
  };

  const showTime = () => {
    if (time) {
      return <p>{time}</p>
    } else {
      return <p>No time yet</p>
    }
  };

  const handleClick = () => {
    if (time) {
      const newTimeList = timeList.push(time);
      console.log(newTimeList); // first time the button is pushed "1" is logged here
      setTimeList(newTimeList);
    }
  };

  const showTimeList = () => {
    if (timeList.length) {
      const timesArr = timeList.map((item) => {
        return <p>item</p>
      });
      return timesArr;
    } else {
      return <p>Time list will go here</p>
    }
  };

  return (
    <div className="App">
      {showTime()}
      {showTimeList()}
      <button onClick={handleClick}>Add this time to the time list</button>
    </div>
  );
}

export default App;

CodePudding user response:

push returns new length of array. What you want is to append time to timeList

const handleClick = () => {
    if (time) {
      const newTimeList = [...timeList, time];
      setTimeList(newTimeList);
      // or
      setTimeList(oldTimeList => ([...oldTimeList, time]));
    }
  };
  • Related