如何在 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?的主要内容,如果未能解决你的问题,请参考以下文章