使用 Axios 和 useState/useEffect 无限重新渲染 React 功能组件?
Infinite Re-rendering of React Functional Component using Axios and useState/useEffect?
我正在尝试使用 Typescript 创建一个 React 功能组件,它将从 API 获取数据,然后将该数据发送到另一个组件,但是,我收到错误消息“错误:太多重新-renders.React 限制渲染的数量以防止无限循环。"
请多多指教!
useEffect(() => {
await axios.get('https://quote-garden.herokuapp.com/api/v3/quotes/random').then((resp) => {
setQuote1(resp.data.data[0]);
});
getQuote();
}, []);
Snippet of Code Causing Error
编辑:
这是发生错误的整个文件。
import React, { useEffect, useState } from 'react';
import { Row, Col, CardGroup } from 'reactstrap';
import axios from 'axios';
import QuoteCard from './QuoteCard';
const MainQuotes = () => {
const [quote1, setQuote1] = useState();
useEffect(() => {
await axios.get('https://quote-garden.herokuapp.com/api/v3/quotes/random').then((resp) => {
setQuote1(resp.data.data[0]);
});
getQuote();
}, []);
return (
<Row>
<Col>
<CardGroup>
<QuoteCard quoteData={quote1} />
</CardGroup>
</Col>
</Row>
);
};
export default MainQuotes;
我们可以得到你的完整代码吗?看来问题出在你的状态钩子上,并弄清楚它到底在做什么。
我现在的猜测是你的状态挂钩“setQuote1”正在以一种导致重新渲染的方式被调用,然后会再次调用你的 useEffect()(因为 useEffect 运行s 在渲染周期结束),因此,再次调用您的 setQuote1 挂钩。这会无限期地重复。
useEffect() 允许依赖关系,并让您能够准确判断何时应调用 useEffect()。
示例:useEffect(() { 代码在这里},[特别注意这个和 运行 只有当这个更新时])。
当您将依赖项数组留空时,只要有任何更新状态,您就会告诉挂钩 运行。这不一定是坏事,但在某些情况下,您只希望 useEffect() 在特定状态更新时 运行。
您的应用程序中的某些东西必须在您不希望它触发您的 useEffect() 挂钩到 运行 时触发它。
根据 quote1 的类型(我假设它是一个字符串)更新为:
const [quote1, setQuote1] = useState('')
useEffect(() => {
function fetchQuote() {
await axios.get('https://quote-garden.herokuapp.com/api/v3/quotes/random')
.then((resp) => {
setQuote1(resp.data.data[0]);
});
}
if (!quote1) {
fetchQuote();
}
}, []);
因为API的响应是一个随机引用,所以你必须根据quote1的值来处理它。这应该可行,因为 quote1 只会在组件挂载后更新(当值为空字符串时),并且后续渲染不会更新状态,因此 useEffect
不会无限循环。
在编辑之前,我假设 axios 请求在 getQuote 函数内部。我更新了我的答案以反映您发布的代码。
如果 API 响应是静态的,因为依赖数组中的项目只有在它们的当前值发生变化时才会导致重新渲染,它只会在第一次状态更新后立即导致重新渲染.
我正在尝试使用 Typescript 创建一个 React 功能组件,它将从 API 获取数据,然后将该数据发送到另一个组件,但是,我收到错误消息“错误:太多重新-renders.React 限制渲染的数量以防止无限循环。"
请多多指教!
useEffect(() => {
await axios.get('https://quote-garden.herokuapp.com/api/v3/quotes/random').then((resp) => {
setQuote1(resp.data.data[0]);
});
getQuote();
}, []);
Snippet of Code Causing Error
编辑: 这是发生错误的整个文件。
import React, { useEffect, useState } from 'react';
import { Row, Col, CardGroup } from 'reactstrap';
import axios from 'axios';
import QuoteCard from './QuoteCard';
const MainQuotes = () => {
const [quote1, setQuote1] = useState();
useEffect(() => {
await axios.get('https://quote-garden.herokuapp.com/api/v3/quotes/random').then((resp) => {
setQuote1(resp.data.data[0]);
});
getQuote();
}, []);
return (
<Row>
<Col>
<CardGroup>
<QuoteCard quoteData={quote1} />
</CardGroup>
</Col>
</Row>
);
};
export default MainQuotes;
我们可以得到你的完整代码吗?看来问题出在你的状态钩子上,并弄清楚它到底在做什么。
我现在的猜测是你的状态挂钩“setQuote1”正在以一种导致重新渲染的方式被调用,然后会再次调用你的 useEffect()(因为 useEffect 运行s 在渲染周期结束),因此,再次调用您的 setQuote1 挂钩。这会无限期地重复。
useEffect() 允许依赖关系,并让您能够准确判断何时应调用 useEffect()。
示例:useEffect(() { 代码在这里},[特别注意这个和 运行 只有当这个更新时])。
当您将依赖项数组留空时,只要有任何更新状态,您就会告诉挂钩 运行。这不一定是坏事,但在某些情况下,您只希望 useEffect() 在特定状态更新时 运行。
您的应用程序中的某些东西必须在您不希望它触发您的 useEffect() 挂钩到 运行 时触发它。
根据 quote1 的类型(我假设它是一个字符串)更新为:
const [quote1, setQuote1] = useState('')
useEffect(() => {
function fetchQuote() {
await axios.get('https://quote-garden.herokuapp.com/api/v3/quotes/random')
.then((resp) => {
setQuote1(resp.data.data[0]);
});
}
if (!quote1) {
fetchQuote();
}
}, []);
因为API的响应是一个随机引用,所以你必须根据quote1的值来处理它。这应该可行,因为 quote1 只会在组件挂载后更新(当值为空字符串时),并且后续渲染不会更新状态,因此 useEffect
不会无限循环。
在编辑之前,我假设 axios 请求在 getQuote 函数内部。我更新了我的答案以反映您发布的代码。
如果 API 响应是静态的,因为依赖数组中的项目只有在它们的当前值发生变化时才会导致重新渲染,它只会在第一次状态更新后立即导致重新渲染.