由于其初始状态(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 }],
},
],
答案 0 :(得分:2)
更新:根据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返回一个空列表,建议您将undefined
或null
设置为chartData
的初始值:
const [chartData, setChartData] = useState(null);
在这种情况下,您可以保持现状。
答案 1 :(得分:1)
如果我没记错的话,您可以简单地使用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完成提取
答案 2 :(得分:0)
最简单的方法是对代码进行简单的小改动:
{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);
答案 3 :(得分:0)
您需要将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]);