为了账号安全,请及时绑定邮箱和手机立即绑定

仅在 API 请求完成后渲染组件 React hooks

仅在 API 请求完成后渲染组件 React hooks

白猪掌柜的 2023-05-18 09:51:15
当我的图表组件呈现时出现错误,因为它的初始状态是 API 响应之前的空数组。它会说这样的话Cannot read property '0' of undefined是因为当组件加载时,它的初始状态是,好吧......一个空数组。所以我想知道是否有办法让组件仅在收到 API 响应后才呈现。这是父组件:function InformationPage({    match: {        params: { symbol },    },}) {    const [chartData, setChartData] = useState([]); {/*Declaring state*/}useEffect(() => {  {/*Fetching API response here to set state*/}    axios        .get(            `https://finnhub.io/api/v1/stock/candle?symbol=${symbol}&resolution=15&from=1572651390&to=1602623478&token=xxxxxxxxx`        )        .then((res) => {            console.log(res.data);            setChartData(res.data);        })        .catch((err) => {            console.log(err);        });}, [symbol]);return (            <Grid item container xs={12} sm={12} md={6} lg={8}>            {chartData && <QuoteChart chartData={chartData} iex={iex} />}        </Grid>       );}export Default InformationPage;这是子图表组件,基本上当我从 axios 执行获取请求时,它返回一个将映射到对象中的数组chartRender。我只需要找到一种方法来仅在 axios 的 api 请求完成后才呈现组件,以免出现错误。任何帮助将不胜感激。function QuoteChart(props) {    const classes = useStyles();    const { chartData } = props;    const chartRender = chartData.map((chartConfig) => ({        x: new Date(chartConfig?.t),        y: [chartConfig?.o, chartConfig?.h, chartConfig?.l, chartConfig?.c],    }));    // const chartDataLog = console.log(chartData);    const config = {        series: [            {                data: [{ chartRender }],            },        ],
查看完整描述

4 回答

?
开满天机

TA贡献1786条经验 获得超12个赞

更新:根据Finnhub API,它是您从 API 收到的对象,而不是数组。这意味着charData.length在我之前的回答中永远不会被评估true,子组件也QuoteChart永远不会被渲染。

我建议进行以下更改。在您的父组件中,charData = null最初制作:

const [chartData, setChartData] = useState(null);

当 API 返回响应并chartData分配了一个值时,您的子组件可以呈现:

{chartData && <QuoteChart chartData={chartData} iex={iex} />}

您要在子组件中呈现的图表需要以下输入:[{ x: date, y: [O,H,L,C] }]。因为map()只能在数组上调用而chartData不是一个数组,所以您应该导航到所述对象内的数组之一,例如chartData.t

const chartRender = chartData.t.map((timestamp, index) => ({

    x: new Date(timestamp),

    y: [chartData.o[index], chartData.h[index], chartData.l[index], chartData.c[index]],

}));

最后,series.data需要一个数组,你不需要另外将它包装在一个对象中。所以这应该有效:


const config = {

    series: [{

        data: chartRender

    }]

};

您chartData使用空数组进行初始化,因此您的条件应如下所示:


{chartData.length && <QuoteChart chartData={chartData} iex={iex} />}

如果您希望 API 返回一个空列表,我建议设置一个undefinedornull作为 的初始值chartData:


const [chartData, setChartData] = useState(null);

在这种情况下,您可以保持现状。


查看完整回答
反对 回复 2023-05-18
?
慕尼黑5688855

TA贡献1848条经验 获得超2个赞

如果我没记错的话,你可以简单地使用 async/await 来解决你的问题。因此,将 useEffect 行更改为

useEffect(async () => {  {/*Fetching API response here to set state*/}

进而

 await axios
    .get(
            `https://finnhub.io/api/v1/stock/candle?symbol=${symbol}&resolution=15&from=1572651390&to=1602623478&token=xxxxxxxxx`
    )

然后你的应用程序应该等待 axios 完成获取


查看完整回答
反对 回复 2023-05-18
?
开心每一天1111

TA贡献1836条经验 获得超12个赞

最简单的方法需要对代码进行简单的小改动:

 {chartData.length && <QuoteChart chartData={chartData} iex={iex} />}

研究 finnhub 后 - 我发现响应不是数组。我测试了这个网址:

https://finnhub.io/api/v1/stock/candle?symbol=AAPL&resolution=15&from=1572651390&to=1602623478&token=

响应是一个具有“c”属性的对象。您的代码应该相应地修改。对于上面的链接示例:

setChartData(res.data.c);


查看完整回答
反对 回复 2023-05-18
?
慕神8447489

TA贡献1780条经验 获得超1个赞

您需要将 axios 调用包装在异步函数中,wait然后


useEffect(() => {  {/*Fetching API response here to set state*/}

    

   const getInfo = async () => {

       await res = axios

        .get(

            `https://finnhub.io/api/v1/stock/candle?symbol=${symbol}&resolution=15&from=1572651390&to=1602623478&token=xxxxxxxxx`

        )

        console.log(res.data);

        setChartData(res.data);

   }


   getInfo()

}, [symbol]);


查看完整回答
反对 回复 2023-05-18
  • 4 回答
  • 0 关注
  • 132 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信