【问题标题】:Setting state with React Hooks + Fetch API does not trigger re-render使用 React Hooks + Fetch API 设置状态不会触发重新渲染
【发布时间】:2019-07-31 22:33:53
【问题描述】:

我正在尝试通过构建一个简单的域可用性检查器来学习 React Hooks。具体来说,我在玩useState()

目的只是有一个输入字段,用户在其中键入关键字,按 Enter,然后应用程序将对该关键字运行具有多个不同域结尾的提取请求。

这是我的 App 组件(或在此处检查代码框:https://codesandbox.io/s/5410rkrq1p

const App = () => {
  const domainEndings = [
    ".ws",
    ".ga",
    ".cf",
    ".tk",
    ".ml",
    ".gq",
    ".kz",
    ".st",
    ".fm",
    ".je"
  ];

  const [domainString, setDomainString] = useState("");
  const [domainsArray, setDomainsArray] = useState([]);
  const [lookedUpDomainsArray, setLookedUpDomainsArray] = useState([]);

  const handleDomainChange = event => {
    setDomainString(event.target.value);
    setDomainsArray(
      domainEndings.map(ending => event.target.value.trim() + ending)
    );
  };

  let testArray = [];

  const runDomainLookup = url => {
    return fetch(
      `https://domainr.p.rapidapi.com/v2/status?domain=${url}&mashape-key=${myAPIKEY}`
    )
      .then(res => res.json())
      .then(data => {
        testArray.push({
          url: data.status[0].domain,
          status: data.status[0].status
        });
        setLookedUpDomainsArray(testArray);
      });
  };

  const handleSubmit = e => {
    e.preventDefault();
    setLookedUpDomainsArray([]);
    testArray = [];
    domainsArray.map(eachDomain => runDomainLookup(eachDomain));
  };

  return (
    <div>
      <form onSubmit={handleSubmit}>
        <input
          value={domainString}
          placeholder="type keyword then hit enter"
          onChange={e => handleDomainChange(e)}
        />
      </form>
      {lookedUpDomainsArray &&
        lookedUpDomainsArray.map((domain, index) => {
          return (
            <div key={index}>
              {domain.url} is {domain.status}
            </div>
          );
        })}
    </div>
  );
};

我遇到的错误是:

  • 状态似乎设置正确(在 React 开发工具中检查)。

  • 来自映射的 fetch 请求的第一个响应正确地呈现给 DOM

  • 在用户按下输入字段中的键之前,不会触发新添加的状态(来自获取请求)的重新渲染

这是一个演示视频:https://streamable.com/klshu

您会注意到,在我开始在输入中输入其他字符之前,其余结果不会出现

提前谢谢????

【问题讨论】:

    标签: reactjs fetch fetch-api


    【解决方案1】:

    谢谢!是的,我尝试过 Promise.all(),但是我希望每个 fetch 请求单独运行(例如,如果一个 fetch 请求超时,它将阻止所有其他请求)。

    Reddit找到解决方案

    本质上,当通过 Hooks 设置状态时,我应该已经通过了之前的状态:

    const runDomainLookup = url => {
        return fetch(
          `https://domainr.p.rapidapi.com/v2/status?domain=${url}&mashape-key=${myAPIKEY}`
        )
          .then(res => res.json())
          .then(data => {
            setLookedUpDomainsArray(prevArray => [
              ...prevArray,
              {
                url: data.status[0].domain,
                status: data.status[0].status
              }
            ]);
          });
      };
    

    CodeSandbox 上的工作解决方案:https://codesandbox.io/s/51ky3r63x

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-06-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-07
      • 2020-07-26
      • 2020-07-13
      相关资源
      最近更新 更多