Lors de l'initialisation du composant widget qui charge divers graphiques, il fonctionne comme il se doit, mais lors du passage à un autre ListItem, componentDidMount ne se charge pas lors du passage à un autre élément. J'ai besoin de le charger, car il récupère les données requises pour cela. Mais le problème est que lorsque je passe d'un ListItem à un autre, je n'ai pas initialisé componentDidMount
DashboardSidebar.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 ( ... ); } }
Ce composant semble fonctionner correctement, mais en cliquant sur un autre ListItem
exécutez componentDidUpdate
qui ne récupère pas les données requises pour les graphiques. Je découvre également que lorsque j'ai changé dans MainDashboard le composant key = {i}
en key = {l.id}
est commencé à frapper componentDidMount
, mais les widgets ne se chargent pas, mais à partir de la console, je peux voir qu'il a frappé componentDidMount
et récupère les données que je console.log ()
.
MainDashboard.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> ) } }
3 Réponses :
Donc, componentDidMount
est effectivement touché mais rien ne se passe en termes de mises à jour des données? dans ce cas, votre composant se charge / monte en premier et tout ce qui doit se passer ne déclenche pas un nouveau rendu, j'envisagerais d'utiliser une autre méthode de cycle de vie pour m'assurer que vos données sont mises à jour.
Je ne sais pas si vous travaillez sur un système hérité, mais si la mise à niveau vers des composants fonctionnels est une option, je recommanderais d'utiliser la méthode du cycle de vie useEffect
car elle remplace de nombreuses méthodes de cycle de vie comme < code> componentDidMount , componentDidUpdate
et le componentWillUnmount
unsafe et vous rendront la vie beaucoup plus facile et plus efficace.
Un nouveau rendu ne réexécutera pas componentDidMount
.
componentDidMount
n'est exécuté que lorsqu'un composant est monté.
Une mise à jour de l'état dans DashboardSidebar
ne provoquerait pas le remontage de BaseDashboard
, donc componentDidMount
ne sera pas réexécuté pour BaseDashboard code>.
Avez-vous essayé de récupérer les données dans le gestionnaire d'événements onChange
(pour passer à un autre ListItem
) à la place?
Vous avez trois options:
1- Utilisez un autre cycle de vie tel que componentDidUpdate
, récupérez les nouvelles données s'il y a un changement particulier dans les accessoires ou l'état
2- Utilisez une nouvelle Key
, si vous utilisez une nouvelle clé sur un composant, cela déclenchera un componentDidMount
, car le composant est à nouveau rendu en tant que nouvelle entité
3- Utilisez react.ref
Je pense que vous devriez lire les trois choix et choisir celui qui vous conviendra le mieux.
En HTML ou en React des événements synthétiques , vous n'obtenez pas
evt.value code >, mais
evt.target.value
, donc ce qui suit:_onSwitchTab = (value) => ...
n'est pas valide, il devrait être_onSwitchTab = (evt ) => {const value = evt.target.value
. Si cela ne fonctionne pas, vous devriez nous montrer ce que fait la fonctionsetCurrentDashboard
@Tyblitz J'ai changé le
_onSwitchTab
devalue
àevt
et mis en valeur, mais cela ne fonctionne pas. Oui, je mettrai à jour ma question avec setCurrentDashboard@PrakashKarena non,
_onSwitchTab
n'est pas le problèmevous souhaitez appeler votre demande de récupération dans BaseDashboard.jsx lorsqu'un lien $ {path} / $ {report.slug} } /> dans DashboardSidebar.jsx est cliqué. ???