onClick时使用useEffect

时间:2020-08-26 10:53:06

标签: reactjs react-hooks

我对如何将特效与应用逻辑结合使用感到困惑。

假设此组件:

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>
  );
}

我想要那个:

  • (仅)当用户单击按钮时,将使用输入的正确查询值运行获取操作
  • 如果抓取仍在进行中,并且用户单击,则抓取将被跳过,但是会触发效果(意味着:我有意不禁用按钮,我希望运行效果功能,但我在其中进行了检查函数不执行提取操作。

问题:

  • 该效果不应在坐骑上触发(这没有任何意义)
  • 查询更改时不会触发效果,但是如果我不将查询变量放在useEffect依赖项数组中,React会抱怨(react-hooks / exhaustive-deps)
  • 当用户单击按钮时,效果应触发;例如,我使用伪造状态isRun,设置onClick={setIsRun(true)},根据[isRun]进行效果,在效果功能的末尾设置setIsRun(false)并检查{ {1}}在效果函数的开头,以防止由于效果本身将when设置为false时,由于状态改变,它会再次运行。这行得通,但我觉得它很冗长和不舒服...
  • 如果再次单击按钮(是否具有相同的if (!isRun)值)并且没有运行提取操作,前一个提取操作仍未完成,则效果应触发:使用带有query的先前解决方案因为isRun已设置为isRun,所以不会触发,因此状态不会改变;也许在另一种状态下有一种方法,但是又很冗长又违反直觉。
  • 最重要的是:该代码应简洁易读,而无需使用“技巧”!

您将如何编写这样的组件?

2 个答案:

答案 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>
  );
}