Lorsque je passerai à cet écran, il fera quelques appels API pour récupérer les dernières données. Mais il ne semble pas déclencher l'événement didFocus pour déclencher les appels de l'API lorsque je passe d'une autre pile de navigation avec la version hooks alors que cela fonctionne bien avec la version classe.
Comment puis-je faire en sorte que la version des hooks ait le même comportement que la version de classe?
Quelle est la différence entre ces deux versions?
class someScreen extends Component {
componentDidMount() {
const {
navigation,
} = this.props;
this.navFocusListener = navigation.addListener('didFocus', () => {
// do some API calls here
console.log("class version");
API_CALL();
});
}
componentWillUnmount() {
this.navFocusListener.remove();
}
}
transition d'une autre pile de navigation vers cet écran: version de classe
transition entre les écrans d'une même pile: version classe
const someScreen = ({
navigation,
}) => {
useEffect(() => {
const navFocusListener = navigation.addListener('didFocus', () => {
// do some API calls here
API_CALL();
console.log('hooooks');
});
return () => {
navFocusListener.remove();
};
}, []);
}
transition d'une autre pile de navigation vers cet écran: rien ne s'affiche dans la console
transition entre les écrans d'une même pile: hooooks
BTW, voici la solution de contournement que j'ai trouvée
const someScreen = ({
navigation,
}) => {
useEffect(() => {
const isFocused = navigation.isFocused();
// manually judge if the screen is focused
// if did, fire api call
if (isFocused) {
// do the same API calls here
API_CALL();
console.log('focused section');
}
const navFocusListener = navigation.addListener('didFocus', () => {
// do some API calls here
API_CALL();
console.log('listener section');
});
return () => {
navFocusListener.remove();
};
}, []);
}
sortie console
transition d'une autre pile de navigation vers cet écran: section ciblée
transition entre les écrans d'une même pile: section d'écoute
Je suppose que j'ai trouvé la cause première du comportement incohérent. Il existe un autre hook appelé useLayoutEffect
useLayoutEffect La signature est identique à useEffect, mais elle se déclenche de manière synchrone après toutes les mutations DOM. Utilisez-le pour lire la disposition du DOM et effectuer un nouveau rendu synchrone. Les mises à jour planifiées dans useLayoutEffect seront vidées de manière synchrone, avant que le navigateur ait la possibilité de peindre.
useLayoutEffect bloquera la peinture tandis que useEffect ne le fera pas. Cela confirme et explique ma supposition que l'événement didFocus s'est déclenché, mais cela n'a pas déclenché l'auditeur car il manque le timing
donc dans mon cas, je dois utiliser useLayoutEffect au lieu de useEffect
référence: https://kentcdodds.com/blog/useeffect-vs-uselayouteffecthttps://reactjs.org/docs/hooks-reference.html#uselayouteffect