我正在尝试学习使用商店的反应。我想做的是拥有2个组件(一个主组件和一个子组件),我想调用API用于主要组件中的数据,并将此数据传递给子组件,然后在react-chartjs-2组件中呈现此数据。
这是我的主要组件(Home.tsx),它调用UserData的API(我从后端正确地以数组[]的形式接收数据。
import React, { useEffect, useState } from "react";
import { History } from "history";
import { connect } from "react-redux";
import { ApplicationState } from "../../store";
import { actionCreators, reducer } from "../../store/auth";
import axios from 'axios';
import 'antd/dist/antd.css'
import { Card, Button } from 'antd';
import BalanceChart from "./child-components/BalanceChart";
type HomeProps = ReturnType<typeof reducer>
& typeof actionCreators
& { readonly history: History };
const Home: React.FC<HomeProps> = ({
id,
historicalBalanceValues
}) => {
const [balanceValue, setBalanceValue] = React.useState([]);
const getUserRequest = async () => {
let response = await axios({
url: `https://localhost:44340/api/users/${id}`,
method: 'get'
});
return response.data;
};
useEffect(() => {
id = sessionStorage.getItem("userId");
getUserRequest()
.then(data => {
setBalanceValue(data.item.balanceValue);
if (!!data.item.historicalBalances){
historicalBalanceValues = data.item.historicalBalances.map(r => r.balanceValue);
}
});
});
return (
<div >
<h1 className='home-header'>Savings</h1>
<div className='card-container'>
<Card style={{ width: 400, marginLeft: '75px' }} title={'Total balance'}>
<div className='balance-container'>
<div className='balance-value'>{balanceValue}</div>
<Button className='goal-button' type='primary' shape='round'>Add goal</Button>
</div>
</Card>
<Card style={{ width: 400, marginLeft: '75px'}} title={'Balance trend'}>
<BalanceChart chartData={historicalBalanceValues}></BalanceChart>
</Card>
</div>
</div>
);
};
const mapStateToProps = (state: ApplicationState) => ({
id: state.auth.id
});
export default connect(mapStateToProps, actionCreators)(Home);
这是我的第二个组件,我要在其中使用从Home组件传递来的数据来显示折线图。
import React, { Component } from 'react';
import { Line } from 'react-chartjs-2';
import axios from 'axios';
import PasswordInput from "../../Login/child-components/PasswordInput";
type BalanceChartState = {
balanceChartData: []
}
let chartOptionsData = {
labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'],
datasets: [{
label: 'Label',
data: this.props.chartData,
backgroundColor: [
'rgba(255, 99, 132, 0.2)'
],
borderColor: [
'rgba(255, 99, 132, 1)',
],
borderWidth: 1
}]
};
export class BalanceChart extends Component<{chartData: any}, BalanceChartState> {
componentDidMount() {
this.setState({balanceChartData: this.props.chartData})
}
render() {
const { balanceChartData } = this.state;
return (balanceChartData && balanceChartData.length) ?
<Line data={chartOptionsData}></Line> : <Line data={[0]}></Line>
}
}
export default BalanceChart;
问题是,我从一个组件传递到另一组件的数据是'undefined'。我认为对API的数据调用发生在组件渲染之后,但是我不知道该如何实现。组件渲染后,我想传递数据。我想知道什么是达到此目的的良好做法。谢谢
哦,所以我向父(Home)组件添加了条件渲染。渲染现在看起来像这样:
<Card style={{ width: 400, marginLeft: '75px'}} title={'Balance trend'}>
{
!!historicalBalanceValues ?
<BalanceChart chartData={historicalBalanceValues}></BalanceChart> : <Spin/>
}
</Card>
所以现在我有无限的预加载器(historicalBalanceValues是未定义的),甚至艰难的API调用也向我返回了一个其值不表示BalanceChart组件的数组。我认为条件渲染仅以某种方式检查一次。我该如何实现以应对变化?
我找到了解决方案,并且确实将两个组件都更改为类组件。我使用道具在它们之间传递数据,并使用State存储来自Home组件内部后端的数据。感谢您的帮助!