我是React.js的新手第一次加载代码显示错误,当我评论这部分{data.advice}并运行它时,它向我显示html,它还调用API 2次,它在重新加载时给出错误。如何修复它?
import { Box, Button, Card, CardActions, CardContent, Container, Typography } from '@mui/material';
import axios from 'axios';
import React, { useEffect, useState } from 'react';
const Advice = () => {
const [data, setData] = useState(null);
const clicked = () => {
callAPI();
}
const callAPI = () => {
axios.get('https://api.adviceslip.com/advice')
.then(respone => {
setData(respone.data.slip)
console.log(respone.data.slip);
})
.catch((error) => {
console.log(error);
})
}
useEffect(() => {
callAPI();
}, [])
return (
<Box>
<Container>
<Typography variant='h2' sx={{ textAlign: "center" }}>Advice App</Typography>
<Card sx={{ maxWidth: 500, margin: "10px auto", display: "block", textAlign: "center" }}>
{/* <CardMedia
sx={{ height: 140 }}
image="/static/images/cards/contemplative-reptile.jpg"
title="green iguana"
/> */}
<CardContent>
<Typography gutterBottom variant="h5" component="div">
Advice of the Day
</Typography>
<Typography variant="body2" color="text.secondary">
{data.advice}
</Typography>
</CardContent>
<CardActions>
<Button size="small" onClick={clicked}>Share</Button>
<Button size="small">Learn More</Button>
</CardActions>
</Card>
</Container>
</Box>
);
};
export default Advice;
https://codesandbox.io/s/cool-wildflower-p7k6ee?file=/src/App.js
任何帮助将不胜感激
4条答案
按热度按时间pxy2qtax1#
正如评论中提到的
你得到的错误,因为你的代码是试图打印建议属性的数据,甚至在它被初始化。你可以尝试下面的代码,以确保它会打印时,数据是存在的。
发送两个API调用的可能原因可能是因为您的应用组件 Package 在
<strict>
标签中。这意味着react在严格模式下运行。这将调用您的效果两次,而react将仅在开发模式下执行。所以这很好。没什么可担心的。reference:React 18 strict mode causing component to render twice9njqaruj2#
在第一次运行时,您的
data
变量是null
(来自useState(null)
),因此尝试访问data.advice
会触发错误,因为您无法访问null
值的对象属性。有很多方法可以解决这个问题,但最简单的两个(现在就完成你的工作)是:
const [data, setData] = useState({ advice: null });
-将data
的初始值替换为一个对象。然后data.advice
将在第一次运行时渲染null
,并且什么都不可见。您也可以使用一个正在加载消息来代替null
,如...{ advice: 'Loading...' });
。1.使用
{data && data.advice || null
或data ? data.advice : null
保护显示的表达式({data.advice}
),无论您喜欢哪种。加载消息代替null
也是可能的。双重网络调用可能是由于Advice组件在页面加载时被其包含组件渲染了两次(或自动重新渲染)(因此运行了
useEffect
钩子两次)。您需要进一步调试才能捕捉到这一点,为了帮助我们,您需要使用容器组件的代码更新您的问题,以便我们可以捕捉到问题。hyrbngr73#
你在第一次渲染时得到一个错误的原因是因为你有“data”初始化为null。“data”是null,因此没有“advice”属性,你应该得到的错误是“Cannot read property of null”。
use Effect钩子在渲染后调用。
useEffect做什么?通过使用这个Hook,你告诉React你的组件需要在render之后做一些事情。React会记住你传递的函数(我们将其称为“effect”),并在执行DOM更新后调用它。在这个effect中,我们设置文档标题,但我们也可以执行数据获取或调用其他命令式API。
来源:https://legacy.reactjs.org/docs/hooks-effect.html
旁注:这些是过时的文档,但它们应该是正确的,关于这种行为。
@CodeThing提供的解决方案应该可以修复这个错误。它会检查“data”是否存在,如果不存在,它会立即返回false,并且不检查“data.advice”。
另一方面,你可以使用advice属性将数据初始化为object,并将其设置为空字符串:{建议:““}
希望这有帮助:)
ogsagwnx4#
因为你为数据设置了null,然后你试图把它作为一个 object 来访问。你应该使用一个条件。例如: