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

Pac*_*mit 0 javascript rest reactjs axios 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;
Run Code Online (Sandbox Code Playgroud)

这是子图表组件,基本上当我从 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 }],
            },
        ],
Run Code Online (Sandbox Code Playgroud)

0x2*_*9A3 8

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

我建议进行以下更改。在您的父组件中,charData = null首先进行以​​下操作:

const [chartData, setChartData] = useState(null);
Run Code Online (Sandbox Code Playgroud)

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

{chartData && <QuoteChart chartData={chartData} iex={iex} />}
Run Code Online (Sandbox Code Playgroud)

您想要在子组件中呈现的图表需要以下输入:[{ 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]],
}));
Run Code Online (Sandbox Code Playgroud)

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

const config = {
    series: [{
        data: chartRender
    }]
};
Run Code Online (Sandbox Code Playgroud)

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

{chartData.length && <QuoteChart chartData={chartData} iex={iex} />}
Run Code Online (Sandbox Code Playgroud)

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

const [chartData, setChartData] = useState(null);
Run Code Online (Sandbox Code Playgroud)

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