我对如何将特效与应用逻辑结合使用感到困惑。
假设此组件:
import React, { useEffect, useState } from "react";
export default function App() {
const [query, setQuery] = useState('');
useEffect( () => {
fetch('https://www.google.com?q='+query)
.then(response => console.log(response))
}); // depends on what?
return (
<div>
<input onChange={e => setQuery(e.target.value)} value={query} />
<button>Ask Google about {query}</button>
</div>
);
}
我想要那个:
问题:
isRun
,设置onClick={setIsRun(true)}
,根据[isRun]
进行效果,在效果功能的末尾设置setIsRun(false)
并检查{ {1}}在效果函数的开头,以防止由于效果本身将when设置为false时,由于状态改变,它会再次运行。这行得通,但我觉得它很冗长和不舒服... if (!isRun)
值)并且没有运行提取操作,前一个提取操作仍未完成,则效果应触发:使用带有query
的先前解决方案因为isRun
已设置为isRun
,所以不会触发,因此状态不会改变;也许在另一种状态下有一种方法,但是又很冗长又违反直觉。您将如何编写这样的组件?
答案 0 :(得分:2)
听起来您根本不应该使用useEffect
。您希望这是在用户操作上发生,而不是在效果上发生:
(仅当)用户单击按钮时,将使用输入的正确查询值运行获取操作
删除useEffect
并创建一个函数来处理点击:
const handleClick = (e) => {
fetch('https://www.google.com?q='+e.target.value)
.then(response => console.log(response));
};
并将该函数传递给组件:
<button onClick={handleClick}>Ask Google about {query}</button>
这些要求似乎令人困惑:
- 如果抓取仍在进行中并且用户单击,则会跳过抓取操作,但会触发效果
- 如果再次单击按钮(具有或不具有相同的查询值)并且未运行提取之前尚未完成上一次提取,则效果应触发
该函数唯一要做的就是执行fetch
。那么该操作是否应该发生?您建议的将状态保持在变量(isRun
)中的解决方案可以确定在这种情况下是否应该发生状态。我认为,当您真正想要的只是一个函数时,之前的问题就是将其与useEffect
混合在一起。添加isRun
来声明并在执行操作时相应地对其进行更新:
const [isRun, setIsRun] = useState(false);
const handleClick = (e) => {
if (isRun) { return; }
setIsRun(true);
fetch('https://www.google.com?q='+e.target.value)
.then(response => {
console.log(response);
setIsRun(false);
});
};
答案 1 :(得分:1)
我不确定您是否要坚持使用useEffect
,但似乎不适用于这种情况。我能做的就是单击按钮时调用一个函数。
import React, { useEffect, useState } from "react";
export default function App() {
const [query, setQuery] = useState('');
const handleQuery = (query) => {
fetch('https://www.google.com?q='+query)
.then(response => console.log(response))
}
return (
<div>
<input onChange={e => setQuery(e.target.value)} value={query} />
<button onClick={() => handleQuery(query)}>Ask Google about {query}</button>
</div>
);
}