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

当我的图表组件呈现时出现错误,因为它的初始状态是 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 }],

            },

        ],


白猪掌柜的
浏览 141回答 4
4回答

开满天机

更新:根据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);在这种情况下,您可以保持现状。

慕尼黑5688855

如果我没记错的话,你可以简单地使用 async/await 来解决你的问题。因此,将 useEffect 行更改为useEffect(async&nbsp;()&nbsp;=>&nbsp;{&nbsp;&nbsp;{/*Fetching&nbsp;API&nbsp;response&nbsp;here&nbsp;to&nbsp;set&nbsp;state*/}进而&nbsp;await&nbsp;axios &nbsp;&nbsp;&nbsp;&nbsp;.get( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`https://finnhub.io/api/v1/stock/candle?symbol=${symbol}&resolution=15&from=1572651390&to=1602623478&token=xxxxxxxxx` &nbsp;&nbsp;&nbsp;&nbsp;)然后你的应用程序应该等待 axios 完成获取

开心每一天1111

最简单的方法需要对代码进行简单的小改动:&nbsp;{chartData.length&nbsp;&&&nbsp;<QuoteChart&nbsp;chartData={chartData}&nbsp;iex={iex}&nbsp;/>}研究 finnhub 后 - 我发现响应不是数组。我测试了这个网址:https://finnhub.io/api/v1/stock/candle?symbol=AAPL&resolution=15&from=1572651390&to=1602623478&token=响应是一个具有“c”属性的对象。您的代码应该相应地修改。对于上面的链接示例:setChartData(res.data.c);

慕神8447489

您需要将 axios 调用包装在异步函数中,wait然后useEffect(() => {&nbsp; {/*Fetching API response here to set state*/}&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;const getInfo = async () => {&nbsp; &nbsp; &nbsp; &nbsp;await res = axios&nbsp; &nbsp; &nbsp; &nbsp; .get(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; `https://finnhub.io/api/v1/stock/candle?symbol=${symbol}&resolution=15&from=1572651390&to=1602623478&token=xxxxxxxxx`&nbsp; &nbsp; &nbsp; &nbsp; )&nbsp; &nbsp; &nbsp; &nbsp; console.log(res.data);&nbsp; &nbsp; &nbsp; &nbsp; setChartData(res.data);&nbsp; &nbsp;}&nbsp; &nbsp;getInfo()}, [symbol]);
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript