【问题标题】:how to get an useEffect inside a function in React?如何在 React 的函数中获取 useEffect?
【发布时间】:2021-07-02 15:07:54
【问题描述】:

我正在尝试为一个项目制作一个倒计时网站。我希望倒计时由按钮触发。我正在使用 React,但我不断收到此错误

React Hook "useEffect" 在函数 "countdown" 中被调用,该函数既不是 React 函数组件也不是自定义 React Hook 函数。 React 组件名称必须以大写字母开头

我对反应很陌生,有人可以给我一些建议来解决这个问题吗?

代码:

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;

【问题讨论】:

标签: javascript reactjs


【解决方案1】:

您可以使用setInterval 代替setTimout

将您的代码修复为:

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;

你试图在一个普通的 javascript 函数中添加 useEffect,这就是为什么它会抛出一个错误,即你调用的 useEffect 在一个不是 React 函数组件的函数中。

【讨论】:

    【解决方案2】:

    useEffect 不应放在函数内。您不需要该开始计数功能。 onClick 可以更新一个状态,并让 useEffect 监听该状态的变化。

    【讨论】:

      【解决方案3】:

      钩子规则:

      ✅ 不要从常规 JavaScript 函数调用 Hooks。

      ✅ 从 React 函数组件调用 Hooks。

      ✅ 从自定义 Hooks 调用 Hooks。

      您正在从一个平面 javascript 函数中调用 hook (useEffect),这违反了 hooks 的规则。

      【讨论】:

        【解决方案4】:

        你不应该在普通的js函数中调用钩子,你可以这样解决你的问题

        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 正在监听count 状态并在1 秒超时内再次执行setCount
        • @Techuila 不,它不会,请检查这里的代码沙箱,同时检查控制台以查看更新日志。 codesandbox.io/s/ecstatic-almeida-90qky?file=/src/App.js
        • @Techuila 不用担心。如果是您投反对票,请回复。谢谢
        猜你喜欢
        • 2021-05-16
        • 2020-09-14
        • 1970-01-01
        • 2023-03-08
        • 2019-11-12
        • 2019-07-27
        • 2020-01-07
        • 2021-04-14
        相关资源
        最近更新 更多