admin管理员组

文章数量:1278985

I'm trying to make an countdown website for a project. I want that the countdown is triggered by a button. I'm using React but i keep getting this error

React Hook "useEffect" is called in function "countdown" that is neither a React function ponent nor a custom React Hook function. React ponent names must start with an uppercase letter

I'm pretty new to react, can somebody give me some advice to fix the problem ?

the code:

import './App.css';
import React, { useEffect, useState } from 'react';

function App() {
  const time = 20;
  const [count, setCount] = useState(time);

  const startCount = () => {
    useEffect(() => {
      if (count > 0) {
        setTimeout(() => setCount(count - 1), 1000);
      } else {
        setCount('Times up');
      }
    });
  };

  return (
    <div className="App">
      <div>{count}</div>
      <button onClick={startCount}> start </button>
      <button> pauze </button>
    </div>
  );
}

export default App;

I'm trying to make an countdown website for a project. I want that the countdown is triggered by a button. I'm using React but i keep getting this error

React Hook "useEffect" is called in function "countdown" that is neither a React function ponent nor a custom React Hook function. React ponent names must start with an uppercase letter

I'm pretty new to react, can somebody give me some advice to fix the problem ?

the code:

import './App.css';
import React, { useEffect, useState } from 'react';

function App() {
  const time = 20;
  const [count, setCount] = useState(time);

  const startCount = () => {
    useEffect(() => {
      if (count > 0) {
        setTimeout(() => setCount(count - 1), 1000);
      } else {
        setCount('Times up');
      }
    });
  };

  return (
    <div className="App">
      <div>{count}</div>
      <button onClick={startCount}> start </button>
      <button> pauze </button>
    </div>
  );
}

export default App;
Share Improve this question asked Apr 6, 2021 at 19:28 bosman2bosman2 592 gold badges2 silver badges8 bronze badges 3
  • 3 useEffect enables you to run something whenever the the ponent is rendered or when a state changes. Having that inside of a function that is called on click makes it useless. useEffect should call other functions, but should never be called from within a function. – Emiel Zuurbier Commented Apr 6, 2021 at 19:34
  • Does this answer your question? Implementing a countdown timer in React with Hooks – Emile Bergeron Commented Apr 6, 2021 at 21:07
  • With a button: stackoverflow./q/62294102/1218980 – Emile Bergeron Commented Apr 6, 2021 at 21:08
Add a ment  | 

5 Answers 5

Reset to default 3

You can use setInterval instead of using setTimout

Fix your code to this:

import './App.css';
import React, { useEffect, useState } from 'react';

function App() {
  const time = 20;
  const [count, setCount] = useState(time);
  const [isStart, setIsStart] = useState(false);


    useEffect(() => {
      if (isStart) {
        const timer = setInterval(() => {
          if (count > 0) {
            setCount(count - 1)
          } else {
            setCount('Times up');
            clearInterval(timer);
          }
        }, 1000);
      }
    }, [isStart]);


  return (
    <div className="App">
      <div>{count}</div>
      <button onClick={() => setIsStart(true)}> start </button>
      <button> pauze </button>
    </div>
  );
}

export default App;

You're trying to add useEffect inside a plain javascript function, that is why it throws an error that the useEffect you called is in a function that is not a React function ponent.

useEffect should not be put inside a function. You do not need that start count function. onClick can update a state, and let useEffect listen to the change of that state.

Rules for hooks:

✅ Don’t call Hooks from regular JavaScript functions.

✅ Call Hooks from React function ponents.

✅ Call Hooks from custom Hooks.

You are calling hook (useEffect) from a plane javascript function which is against the rules of hooks.

You should not call hooks in plain js functions, you can solve your issue like this

import './App.css';
import React, { useEffect, useState } from 'react';

function App() {
  const time = 20;
  const [count, setCount] = useState(time);
  const [start, setStart] = useState(false)

  useEffect(() => {
    if (start) {
      if (count > 0) {
        setTimeout(() => setCount(count - 1), 1000);
      } else {
        setCount('Times up');
      }
    }

  }, [count, start])

  const startCount = () => {
    setStart(true)
  }

  return (
    <div className="App">
      <div>{count}</div>
      <button onClick={startCount}> start </button>
      <button> pauze </button>
    </div>
  );
}

export default App;

useEffect hook don't use in any child function of body ponent function

import React, { useEffect, useState, useCallback } from 'react';
function App() {
  const [count, setCount] = useState();
  useEffect(() => {
    if (count > 0) {
      setTimeout(() => setCount(count - 1), 1000);
    } else {
      setCount('Times up');
    }
  }, [count]);
  return (
    <>
      <div>{count}</div>
      <button onClick={() => setCount(20)}> start </button>
      <button> pauze </button>
    </>)
}
export default App;

本文标签: javascripthow to get an useEffect inside a function in ReactStack Overflow