在 ListItem 之间切换时如何每次调用 componentDidMount
React how to call componentDidMount every time when switching between ListItem
初始化加载各种图表的小部件组件时,它可以正常工作,但是当切换到另一个 ListItem 时, componentDidMount 在切换到另一个项目时不会加载。我需要加载它,因为它会为它获取所需的数据。但问题是当我在 ListItem 之间切换时没有初始化 componentDidMount
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>
)
}
}
该组件似乎 运行 正确,但是当单击其他 ListItem
运行 componentDidUpdate
时,它们不会获取图表所需的数据。我还发现,当我将 MainDashboard 组件 key={i}
更改为 key={l.id}
时,开始点击 componentDidMount
,但随后小部件未加载,但从控制台我可以看到它点击 componentDidMount
并获取我 console.log()
.
的数据
MainDashboard.jsx
class MainDashboard 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}
</div>
);
}.bind(this));
}
render() {
return (
...
);
}
}
所以 componentDidMount
实际上受到了攻击,但在数据更新方面没有发生任何事情?在这种情况下,您的组件 loads/mounts 首先,无论需要发生什么都不会触发重新渲染,我会考虑使用另一种生命周期方法来确保您的数据得到更新。
我不确定您是否在遗留系统上工作,但如果可以选择升级到功能组件,我建议使用生命周期方法 useEffect
,因为它取代了许多生命周期方法,例如 componentDidMount
, componentDidUpdate
和不安全的 componentWillUnmount
会让你的生活更轻松,更有效率。
componentDidMount
仅在挂载组件时执行。
DashboardSidebar
中的状态更新不会导致 BaseDashboard
重新挂载,因此 componentDidMount
不会为 BaseDashboard
.
重新执行
您是否尝试过在 onChange
事件处理程序中获取数据(用于切换到另一个 ListItem
)?
你有三个选择:
1- 使用另一个生命周期,例如 componentDidUpdate
,如果 props 或 state
有特定变化,则获取新数据
2- 使用一个新的Key
,如果你在一个组件上使用一个新的键,它会触发一个componentDidMount
,因为组件被重新渲染为一个新的实体
3- 使用 react.ref
我认为您应该仔细阅读所有三种选择,然后选择最适合您的一种。
初始化加载各种图表的小部件组件时,它可以正常工作,但是当切换到另一个 ListItem 时, componentDidMount 在切换到另一个项目时不会加载。我需要加载它,因为它会为它获取所需的数据。但问题是当我在 ListItem 之间切换时没有初始化 componentDidMount
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>
)
}
}
该组件似乎 运行 正确,但是当单击其他 ListItem
运行 componentDidUpdate
时,它们不会获取图表所需的数据。我还发现,当我将 MainDashboard 组件 key={i}
更改为 key={l.id}
时,开始点击 componentDidMount
,但随后小部件未加载,但从控制台我可以看到它点击 componentDidMount
并获取我 console.log()
.
MainDashboard.jsx
class MainDashboard 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}
</div>
);
}.bind(this));
}
render() {
return (
...
);
}
}
所以 componentDidMount
实际上受到了攻击,但在数据更新方面没有发生任何事情?在这种情况下,您的组件 loads/mounts 首先,无论需要发生什么都不会触发重新渲染,我会考虑使用另一种生命周期方法来确保您的数据得到更新。
我不确定您是否在遗留系统上工作,但如果可以选择升级到功能组件,我建议使用生命周期方法 useEffect
,因为它取代了许多生命周期方法,例如 componentDidMount
, componentDidUpdate
和不安全的 componentWillUnmount
会让你的生活更轻松,更有效率。
componentDidMount
仅在挂载组件时执行。
DashboardSidebar
中的状态更新不会导致 BaseDashboard
重新挂载,因此 componentDidMount
不会为 BaseDashboard
.
您是否尝试过在 onChange
事件处理程序中获取数据(用于切换到另一个 ListItem
)?
你有三个选择:
1- 使用另一个生命周期,例如 componentDidUpdate
,如果 props 或 state
有特定变化,则获取新数据
2- 使用一个新的Key
,如果你在一个组件上使用一个新的键,它会触发一个componentDidMount
,因为组件被重新渲染为一个新的实体
3- 使用 react.ref
我认为您应该仔细阅读所有三种选择,然后选择最适合您的一种。