React hooks useEffect 调用 API 第二次和第一次调用 API 响应也返回
React hooks useEffect call API second time and first time calling API response also returning
我正在使用 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}
我编写了 this 用于获取的教程代码 API
中检查我的确切代码
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
那么为什么显示旧状态?
当组件重新呈现时,挂钩不会重新初始化其中的所有状态。如果是这种情况,状态将无法正常工作(当您更改状态时组件会重新呈现)。
相反,对于每个渲染,useState
挂钩存储并且 returns 它是该渲染的特定值。在您的情况下,当 API_URL
发生变化时,useEffect
会重新运行,但状态变量不会。
来自docs:
This is a way to “preserve” some values between the function calls —
useState is a new way to use the exact same capabilities that
this.state provides in a class. Normally, variables “disappear” when
the function exits but state variables are preserved by 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]);
我正在使用 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}
我编写了 this 用于获取的教程代码 API
中检查我的确切代码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
那么为什么显示旧状态?
当组件重新呈现时,挂钩不会重新初始化其中的所有状态。如果是这种情况,状态将无法正常工作(当您更改状态时组件会重新呈现)。
相反,对于每个渲染,useState
挂钩存储并且 returns 它是该渲染的特定值。在您的情况下,当 API_URL
发生变化时,useEffect
会重新运行,但状态变量不会。
来自docs:
This is a way to “preserve” some values between the function calls — useState is a new way to use the exact same capabilities that this.state provides in a class. Normally, variables “disappear” when the function exits but state variables are preserved by 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]);