Javascript 如何制作倒计时计时器

Javascript 如何制作倒计时计时器,javascript,reactjs,react-hooks,countdown,Javascript,Reactjs,React Hooks,Countdown,我试着用react做倒计时。它将基本上从10倒计时到0,当0时,我将调用一些函数 我找到了一些理想的例子: 但这是一个类组件,我不想用函数组件和钩子来实现,但我不能 我试过: function App() { const [seconds, setSeconds] = useState(10); useEffect(() => { setSeconds(setInterval(seconds, 1000)); }, []); useEffect(() =>

我试着用react做倒计时。它将基本上从10倒计时到0,当0时,我将调用一些函数

我找到了一些理想的例子: 但这是一个类组件,我不想用函数组件和钩子来实现,但我不能

我试过:

function App() {
  const [seconds, setSeconds] = useState(10);
  useEffect(() => {
    setSeconds(setInterval(seconds, 1000));
  }, []);

  useEffect(() => {
    tick();
  });

  function tick() {
    if (seconds > 0) {
      setSeconds(seconds - 1)
    } else {
      clearInterval(seconds);
    }
  }

  return (

    <div className="App">
      <div
        {seconds}
      </div>
    </div>
  );
}

export default App;
从10倒计时到0非常快,不是在10秒内。
我哪里搞错了?

你在乎精度吗?如果是这样,您就不需要设置间隔。如果你不在乎准确度,而且你可能也不在乎,那么你可以安排一个电话在某个时间间隔打勾,而不是相反

const TimeoutComponent extends Component {
  constructor(props) {
    super(props);
    this.state = { countdown: 10 };
    this.timer = setInterval(() => this.tick(), props.timeout || 10000);
  }

  tick() {
    const current = this.state.countdown;
    if (current === 0) {
      this.transition();
    } else {
      this.setState({ countdown: current - 1 }); 
    } 
  }

  transition() {
    clearInterval(this.timer);
    // do something else here, presumably.
  }

  render() {
    return <div className="timer">{this.state.countDown}</div>;
  }
}

你在乎精确吗?如果是这样,您就不需要设置间隔。如果你不在乎准确度,而且你可能也不在乎,那么你可以安排一个电话在某个时间间隔打勾,而不是相反

const TimeoutComponent extends Component {
  constructor(props) {
    super(props);
    this.state = { countdown: 10 };
    this.timer = setInterval(() => this.tick(), props.timeout || 10000);
  }

  tick() {
    const current = this.state.countdown;
    if (current === 0) {
      this.transition();
    } else {
      this.setState({ countdown: current - 1 }); 
    } 
  }

  transition() {
    clearInterval(this.timer);
    // do something else here, presumably.
  }

  render() {
    return <div className="timer">{this.state.countDown}</div>;
  }
}

这取决于你的逻辑。在当前情况下,运行tick方法的useEffect将在每个渲染上运行。你可以在下面找到一个简单的例子

function App() {
  const [seconds, setSeconds] = useState(10);
  const [done, setDone] = useState(false);
  const foo = useRef();

  useEffect(() => {
    function tick() {
        setSeconds(prevSeconds => prevSeconds - 1)
    }
    foo.current = setInterval(() => tick(), 1000)
  }, []);

  useEffect(() => {
    if (seconds  === 0) {
      clearInterval(foo.current);
      setDone(true);
    }
  }, [seconds])

  return (

    <div className="App">
    {seconds}
    {done && <p>Count down is done.</p>}
    </div>
  );
}

在第一个效果中,我们正在进行倒计时。使用callback one设置状态,因为interval会创建一个闭包。在第二个效果中,我们正在检查我们的条件。

这取决于您的逻辑。在当前情况下,运行tick方法的useEffect将在每个渲染上运行。你可以在下面找到一个简单的例子

function App() {
  const [seconds, setSeconds] = useState(10);
  const [done, setDone] = useState(false);
  const foo = useRef();

  useEffect(() => {
    function tick() {
        setSeconds(prevSeconds => prevSeconds - 1)
    }
    foo.current = setInterval(() => tick(), 1000)
  }, []);

  useEffect(() => {
    if (seconds  === 0) {
      clearInterval(foo.current);
      setDone(true);
    }
  }, [seconds])

  return (

    <div className="App">
    {seconds}
    {done && <p>Count down is done.</p>}
    </div>
  );
}
在第一个效果中,我们正在进行倒计时。使用callback one设置状态,因为interval会创建一个闭包。在第二个效果中,我们正在检查我们的条件。

似乎多重useEffect挂钩导致倒数计时每秒运行一次以上

下面是一个简化的解决方案,我们检查useEffect钩子中的秒数,然后:

使用setTimeout在1秒后更新秒数,或 在倒计时结束时,对要调用的函数执行其他操作 这种方法有一些缺点,见下文

功能应用程序{ 常量[秒,设置秒]=React.useState10; React.useffect=>{ 如果秒数>0{ setTimeout=>SetSecondSeconds-11000; }否则{ 设置秒“BOOOOM!”; } }; 回来 {秒} ; } ReactDOM.render,document.getElementById'root' 多重useEffect挂钩似乎导致倒数每秒运行一次以上

下面是一个简化的解决方案,我们检查useEffect钩子中的秒数,然后:

使用setTimeout在1秒后更新秒数,或 在倒计时结束时,对要调用的函数执行其他操作 这种方法有一些缺点,见下文

功能应用程序{ 常量[秒,设置秒]=React.useState10; React.useffect=>{ 如果秒数>0{ setTimeout=>SetSecondSeconds-11000; }否则{ 设置秒“BOOOOM!”; } }; 回来 {秒} ; } ReactDOM.render,document.getElementById'root'
为什么要用钩子?这基本上和普通组件一样多的代码。@Mike'Pomax'Kamermans虽然至少在当前的设置中,它的代码量差不多,但还是有其他原因让我们更喜欢功能组件而不是类组件。功能组件通常更易于阅读和测试,React团队声称在React的未来版本中可能存在性能激励。为什么要使用挂钩?这基本上和普通组件一样多的代码。@Mike'Pomax'Kamermans虽然至少在当前的设置中,它的代码量差不多,但还是有其他原因让我们更喜欢功能组件而不是类组件。功能组件通常更容易阅读,更容易测试,React团队声称React的未来版本中可能会有性能激励。工作完美!!很好用!!