【问题标题】:React hooks useEffect call API second time and first time calling API response also returningReact 钩子 useEffect 调用 API 第二次和第一次调用 API 响应也返回
【发布时间】:2019-12-09 07:24:37
【问题描述】:

我正在获取具有 useEffect 和 API 响应正确的 API,例如

{response: {message: "This is a image link", status: "success"}, error: null}

当我第二次收到下一个 API 调用响应时,如果出现错误,则旧响应不会被删除。它是这样显示的

{response: {message: "This is a image link", status: "success"}, error: TypeError}

我为获取 API 工作了 this 教程代码

在codesandbox查看我的确切代码

import React, { useState } from "react";
import ReactDOM from "react-dom";
import "./styles.css";

const useFetch = (url, options) => {
  console.log("useFetch");
  const [response, setResponse] = React.useState(null);
  const [error, setError] = React.useState(null);

  React.useEffect(() => {
    const FetchData = async () => {
      try {
        const res = await fetch(url, options);
        const json = await res.json();
        setResponse(json);
        // console.log("json - ", json);
      } catch (error) {
        // console.log("error - ", error);
        setError(error);
      }
    };
    FetchData();
  }, [url]);
  return { response, error };
};

function App() {
  const API_URL = `https://dog.ceo/api/breeds/image/random`;
  const [apiUrl, setApiUrl] = useState(API_URL);
  const res = useFetch(apiUrl, {});
  console.log("res - ", res);
  if (!res.response) {
    return <div>Loading...</div>;
  }

  const apiCallAgain = () => {
    const apiUrl = `https://d.ceo/api/breeds/image/q`;
    setApiUrl(apiUrl);
  };
  const dogName = res.response.status;
  const imageUrl = res.response.message;
  return (
    <div className="App">
      <div>
        <button onClick={apiCallAgain}>API Call</button>
        <h3>{dogName}</h3>
        <div>
          <img src={imageUrl} alt="avatar" />
        </div>
      </div>
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

默认打开控制台并检查res对象。现在单击API Call 按钮并再次检查res 对象。当我在启动时使用 useState null 时,为什么会显示旧状态?

【问题讨论】:

  • 请在此处添加相关代码,这样即使不使用第三方服务也能解决

标签: reactjs react-hooks use-effect


【解决方案1】:

当一个组件重新渲染时,钩子不会重新初始化其中的所有状态。如果是这种情况,状态将无法工作(更改状态时组件会重新渲染)。

对于每个渲染,useState 挂钩存储并返回该渲染的特定值。在您的情况下,当 API_URL 更改时,useEffect 会重新运行,但状态变量不会。

来自docs:

这是一种在函数调用之间“保留”一些值的方法—— useState 是一种使用与 this.state 在一个类中提供。通常,变量在以下情况下“消失” 函数退出,但状态变量由 React 保留。

对此的解决方法是重置useEffect 中的响应和错误状态:

 React.useEffect(() => {
    setResponse(null);
    setError(null);
    const FetchData = async () => {
      try {
        const res = await fetch(url, options);
        const json = await res.json();
        setResponse(json);
        // console.log("json - ", json);
      } catch (error) {
        // console.log("error - ", error);
        setError(error);
      }
    };
    FetchData();
  }, [url]);

【讨论】:

  • 我的实验表明setResponse(null)和setError(null)没有被第二次调用。
  • @Elye 没听懂你……你能详细说明一下吗?
  • 我给useFetch(myUrl, option)打了一次电话,它可以工作。第二次调用它,它不再起作用,只是返回相同的结果。我是不是用错了钩子?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-04-13
  • 2022-07-03
  • 2018-09-18
  • 2020-03-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多