如何在 React 的函数中获取 useEffect?

Posted

技术标签:

【中文标题】如何在 React 的函数中获取 useEffect?【英文标题】:how to get an useEffect inside a function in React? 【发布时间】: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;

【问题讨论】:

useEffect 使您能够在组件被渲染或状态改变时运行某些东西。将其包含在单击时调用的函数中使其无用。 useEffect 应该调用其他函数,但绝不应该从函数内部调用。 这能回答你的问题吗? Implementing a countdown timer in React with Hooks 带按钮:***.com/q/62294102/1218980 【参考方案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 不用担心。如果是您投反对票,请回复。谢谢

以上是关于如何在 React 的函数中获取 useEffect?的主要内容,如果未能解决你的问题,请参考以下文章

React(^16.8) 新增特性Hook

react组件初始化接口请求有多个异步依赖参数

如何在 React 的函数中获取 useEffect?

如何在 React 函数组件中不使用 useEffect 钩子获取数据?

Hooks使用规则

Hooks使用规则