skip to Main Content

I tried to call a function inside onClick in stateless functional component but it’s not working. It works when I use statefull component with class Clock extends React.Component and onClick={this.play}.

I have st like this:

const Clock = function() {

  let second = 0;
  let minute = 25;

  const play = function() {
    if (second == 0) {
      second = 59;
    }
  }

  const style2 = {margin: "10px", fontSize: "30px"};
  let min = ('0' + minute).slice(-2);
  let sec = ('0' + second).slice(-2);

  return (
    <div>
      <div id="time-left" style={style2}>{min}:{sec}</div>
      <div id="start_stop" style={style2} onClick={play}>Icon</div>
    <div>
  );
}

ReactDOM.render(<Clock/>,document.getElementById("root"));

3

Answers


  1. try add () to play
    like this => onClick={play()}

    Login or Signup to reply.
  2. React uses states to detect variable changes. the code works but the DOM doesn’t change because react doesn’t know that the variable value has changed, to let react know you need to use ‘useState’:

    reference: react documentation

    like this:

    import React, { useState } from 'react'
    
    const Clock = function () {
      const [second, setSecond] = useState(0)
      // let second = 0;
      const [minute, setMinute] = useState(25)
      // let minute = 25;
    
      const play = function () {
        if (second == 0)
          setSecond(59);
      }
    
      const style2 = {margin: "10px", fontSize: "30px"}
    
      let min = ('0' + minute).slice(-2)
      let sec = ('0' + second).slice(-2)
    
      return (
        <div>
          <div id="time-left" style={style2}>{min}:{sec}</div>
          <div id="start_stop" style={style2} onClick={play()}>Icon</div>
        </div>
      )
    }
    

    To update a variable you use the set function, in this case ‘setSecond’ / ‘setMinute’

    also watch out the closing tags of the jsx/html elements

    plus:
    if you meant to call the function by clicking and not when the page renders, you need to change the code like this:
    with an anonymus funciton, so it doesn’t get triggered on page render but only when clicked

    onClick={() => play()}
    
    Login or Signup to reply.
  3. Your second and minute variables will re-render to the default value each time a render is triggered by a change, such as your click. So you should make use of the useState hook and perhaps useEffect to reduce the value of your minutes and seconds which is what I assume you’re trying to achieve here.

    Here’s how I would refactor this code (Simplified – You can adapt to contain minutes as well):

    const Clock = () => {
        const [seconds, setSeconds] = useState(60);
    
        useEffect(() => {
            if(seconds > 0) {
                setTimeout(() => {
                    setSeconds(seconds - 1)
                }, 1000)
            }
        }, [seconds])
    
        return (
            <React.Fragment>
                <div id="start_stop" onClick={() => setSeconds(59)}>Icon</div>
            </React.Fragment>
    
        )
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search