【发布时间】:2021-09-26 12:41:41
【问题描述】:
嘿,
我有一个 PortfolioPage 组件(下面的代码)通过组件 useEffect 内的 axios 库向我的 api 调用 GET 请求。
请求之后 它使用 setPortfolio 挂钩设置投资组合属性。
然后,我将投资组合传递给 HoldingsChart 组件(添加的组件的代码)。 当我尝试使用在 HoldingsChart 组件中传递的投资组合道具时,它显示投资组合是一个空对象。
我相信这与 setState 的异步方式有关 但是另一个组件(AssetChart)确实得到了正确渲染,所以我找不到问题。 真的很想得到一些帮助。
PortfolioPage 组件代码:
const PortfolioPage = ({match}) =>{
const user = useContext(UserContext)
const [portfolio, setPortfolio] = useState({})
const portfolioId = match.params.portfolioId
useEffect(() => {
// getPortfolio(user.token, portfolioId, setPortfolio)
const getPortfolio = async () => {
const domain = "http://127.0.0.1:8000/api"
await axios.get(domain + `/portfolios/${portfolioId}`,{
headers:{
'Authorization': `Token ${user.token}`
}
})
.then((res) => {
setPortfolio(res.data)
})
}
getPortfolio()
},[])
return (
<React.Fragment>
<AssetChart records={portfolio.records} />
<HoldingsChart portfolio={portfolio}/>
</React.Fragment>
)
}
HoldingsChart 组件代码:
const HoldingChart = ({portfolio}) =>{
const holdings = portfolio.holdings
const totalValue = portfolio.total_value
const [data, setData] = useState([])
useEffect(() =>{
const holdingsPercentages = []
holdings.forEach(holding => holdingsPercentages.push({value: holding.total_value / totalValue}))
setData(holdingsPercentages)
},[])
const renderCustomizedLabel = ({
cx, cy, midAngle, innerRadius, outerRadius, percent, index,
}) => {
const radius = innerRadius + (outerRadius - innerRadius) * 0.5;
const x = cx + radius * Math.cos(-midAngle * RADIAN);
const y = cy + radius * Math.sin(-midAngle * RADIAN);
return (
<text x={x} y={y} fill="black" fontSize="10" textAnchor={x > cx ? 'start' : 'end'} dominantBaseline="central">
{`${data[index].asset} ${(percent * 100).toFixed(0)}%`}
</text>
);
};
return (
<PieChart width={350} height={350}>
<Pie
data={data}
cx={175}
cy={100}
labelLine={false}
label={renderCustomizedLabel}
innerRadius={40}
outerRadius={80}
fill="#8884d8"
dataKey="value"
>
{
data.map((entry, index) => <Cell key={`cell-${index}`} fill={COLORS[index % COLORS.length]} />)
}
<Tooltip/>
</Pie>
</PieChart>
);
}
错误:
TypeError: Cannot read property 'forEach' of undefined
(anonymous function)
C:/Users/David/Desktop/Long-Term/longterm/src/components/assets-comps/HoldingsChart.js:15
12 | const [data, setData] = useState([])
13 | useEffect(() =>{
14 | const holdingsPercentages = []
> 15 | holdings.forEach(holding => holdingsPercentages.push({value: holding.total_value / totalValue}))
| ^ 16 | setData(holdingsPercentages)
17 | },[])
18 |
谢谢
【问题讨论】:
-
如果你写
console.log(portfolio)InsiderHoldingChart组件你看到了什么? -
@monesulhaque 它打印一个空对象
-
如果你这样做,你会看到什么? .then((res) => { console.log(res); setPortfolio(res.data) })
-
@monesulhaque 它打印从 api 返回的对象,它还使用投资组合对象渲染 AssetChart。
-
如果您成功接收数据,那么可能存在一个问题,您的HoldingChart组件在您进行API调用之前呈现。所以请在
holdings.forEach(holding => holdingsPercentages.push({value: holding.total_value / totalValue}))之前检查一下是否为空。
标签: reactjs axios use-effect setstate