通常,当我初始化我的小部件组件时,它会加载它应能正常工作的各种图表,但是当切换到另一个ListItem时,切换到另一个项目时不会加载componentDidMount。我需要加载它,因为它会获取所需的数据。但是问题是当我在ListItem之间切换时没有初始化componentDidMount
DashboardContent.jsx
class DashboardContent extends Component {
constructor(props) {
super(props);
this.props.dashboardList();
this.props.fetchSiteList();
this._onSwitchTab = this._onSwitchTab.bind(this);
}
_onSwitchTab = (value) => {
this.props.setCurrentDashboard({ value });
}
componentDidMount() {}
render() {
const { classes } = this.props;
const { path } = this.props.match;
return (
<div className={classNames(classes.contentWrapper)}>
<div className={classNames(classes.contentInnerWrapper)}>
<Route path="/report/:report" component={BaseDashboard} />
</div>
<div className={classNames(classes.leftSideLayerControlPanelWrapper)}>
<DashboardSidebar
onChange={(event, value) => this._onSwitchTab(value)}
reports={this.props.reports}
tabLocation={this.props.tabLocation} />
</div>
</div>
)
}
}
function mapDispatchToProps(dispatch) {
return bindActionCreators({
dashboardList: dashboardActions.fetchAllDashboards,
setCurrentDashboard: dashboardActions.setCurrentDashboard,
}, dispatch);
}
function mapStateToProps({ app }) {
return {
reports: app.dashboard.dashboardList,
tabLocation: app.dashboard.selectedDashboard
}
}
这里是另一个组件,还有ListItem
DashboardSidebar.jsx
class DashboardSidebar extends Component {
constructor(props) {
super(props);
this.state = {
tabLocation: this.props.tabLocation
};
this.onChange = this.onChange.bind(this);
}
onChange(event) {
this.setState({
tabLocation: event.target.value
});
}
render() {
const { classes } = this.props;
const { path } = this.props.match;
const { reports = [], sites = [] } = this.props;
let fromFilterString = "-"
let toFilterString = "-"
return (
<Drawer
className={classes.drawer}
variant="permanent"
classes={{
paper: classes.drawerPaper,
}}>
<div>
<List>
{reports.map((report) => (
<ListItem
onClick={this.onChange} button key={report.id}>
<ListItemIcon>
<DashboardIcon />
</ListItemIcon>
<ListItemText
disableTypography
primary={
<Typography type="body2">
<Link to={`${path}/${report.slug}`} style={{ color: "#000" }}>
{report.name}
</Link>
</Typography>
}
/>
</ListItem>
))}
</List>
</div>
<Divider light />
</Drawer>
)
}
}
这里是组件的一部分,该组件从DashboardContent.jsx初始化Route。在此组件中,ChartWidget的初始化似乎运行正确,但单击其他ListItem
时,运行componentDidUpdate
并未获取图表所需的数据。我还发现,当我在BaseDashboard组件中将组件key={i}
更改为key={l.id}
时,它开始命中componentDidMount
,但随后未加载小部件,但是从控制台我可以看到它命中了componentDidMount
并获取了我console.log()
。
BaseDashboard.jsx
class BaseDashboard extends Component {
componentDidUpdate(prevProps) {
if (this.props.match.params.report === prevProps.match.params.report) {
return true;
}
let widgets = {};
let data = {};
let layout = {};
fetch(...)
.then(response => response.json())
.then(data => {
...
this.setState({dashboard: data, isLoading: false, layouts: layout });
})
}
componentDidMount() {
this.setState({ mounted: true, isLoading: true });
let widgets = {};
let data = {};
let layout = {};
fetch(...
})
.then(response => response.json())
.then(data => {
...
this.setState({dashboard: data, isLoading: false, layouts: layout });
})
}
sortWidgets(widgets) {
...
return widgets;
}
generateDOM() {
return _.map(this.state.dashboard.widgets, function(l, i) {
....
return (
<div key={i}>
<ChartWidget
visualization={l.visualization}
name={l.visualization.name}
queryId={l.visualization.query.id}
queryParams={queryParams}/>
</div>
);
}.bind(this));
}
render() {
return (
...
);
}
}
ChardWidged.jsx
class ChartWidget extends Component {
..
componentWillUnmount() {
clearInterval(this.state.checkJobStatusIntervalID);
}
_checkJobStatus() {
this.props.fetchLatestJobStatus(this.props.queryId, this.props.dataset.jobId);
}
componentDidMount() {
this.props.addDataset(this.props.queryId, this.props.visualization.query.latest_query_data_id);
if(this.props.dataset && this.props.dataset.resultId > 0)
{
this.props.fetchQueryResult(this.props.queryId, this.props.dataset.resultId)
} else
{
this.props.startRefreshJob(this.props.queryId, this.props.queryParams)
}
}
componentDidUpdate(prevProps, prevState) {
}
_setJobStatusCheckInterval(isLoading) {
...
}
render() {
...
return (
<Card className={classes.chartWidgetPaper}>
<CardContent className={classes.chartWidgetPaper}>
{headline}
{divider}
{content}
</CardContent>
</Card>
);
}
}
所以componentDidMount
实际上被命中了,但是在数据更新方面什么也没发生?在这种情况下,您的组件将首先加载/挂载,无论发生什么情况都不会触发重新渲染,我会考虑使用另一种生命周期方法来确保您的数据得到更新。
[我不确定您是否在旧系统上工作,但是如果可以选择升级到功能组件,我建议您使用生命周期方法useEffect
,因为它可以替代许多生命周期方法,例如componentDidMount
,componentDidUpdate
和不安全的componentWillUnmount
,将使您的生活更轻松,更高效。