Bonjour,
Dans cet exo:
[(https://grafikart.fr/tutoriels/composant-react-1315#autoplay)]
En 11:56 pour le composant "Clock":
componentDidMount() {
this.timer = window.setInterval(this.tick.bind(this), 1000);
}
Et en 15:21 dans "Incrementer":
componentDidMount() {
window.setInterval(this.tick.bind(this), 1000);
}
Question : Pourquoi dans le 2ème cas, pas besoin d'utiliser "this.timer = " ?
Comment Timer se met à jour sans ça ?
Bonjour, la donnée this.timer
contient l'identiant de la ressource (ressource id) qui à été ouverte par l'appel à setInterval
(en principe la ressource id s'exprime sous la forme d'un nombre entier).
Le fait de ne pas stocké la ressource id n'empêche pas le timer de fonctionner (c'est uniquement l'invalidité de la fonction de rappel qui pourrait l'empêché de fonctionner)
par contre cela empêche de fermer le l'interval car au moment où ton composant et démonté de l'arbre (lorsque que la méthode de cycle de vie componentWillUnmount et déclenchée) tu devrais être en capacité de stoppé la consommation de ressource par ton composant.
Pour un timer (setInterval
) la libération de ressource ce fait via la fonction clearInterval
qui a besoin que d'un seul paramètre la ressource id qu'il doit stoppé.
une implémentation correcte de setInterval
dans un composant React pourrait être:
import React from 'react'
class Timer extends React.Component {
constructor(props) {
super(props)
this.state {
currentTime: 0
}
// sauvegardera la ressource id
this.timeId = null;
// bind la method onIncrement pour que this passe référence au composant dans la méthode onIncrement
this.onIncrement = this.onIncrement.bind(this);
}
// le composant est monté, ouvre l'interval
componentDidMount() {
this.timeId = setInterval(this.onIncrement, 1000);
}
// le composant est démonté, ferme l'interval
componentWillUnmount() {
clearInterval(this.timeId);
}
onIncrement() {
this.setState(currentState => ({
...currentState,
currentTime: currentState.currentTime + 1
}));
}
render() {
return <p>{this.state.currentTime}</p>
}
}
export default Timer
Si la ressouce id n'est pas capturé
this.timeId = setInterval(this.onIncrement, 1000);
et que l'on écrit cela à la place
setInterval(this.onIncrement, 1000);
notre interval ne sera pas fermé lorsque le composant sera démonté
componentWillUnmount() {
// cela ne fermerait pas l'interval car this.timeId serait null il ne contiendrait pas une ressource id
clearInterval(this.timeId);
}
Ce qui provoquerait une fuite de mémoire qui serait visible dans la console via un message d'erreur qui indiquerait:
Can't perform a React state update on an unmounted component