{"componentChunkName":"component---src-templates-blog-post-js","path":"/fr/making-setinterval-declarative-with-react-hooks/","result":{"data":{"site":{"siteMetadata":{"title":"Ibrahim personal blog","author":"Ibrahim"}},"markdownRemark":{"id":"c5f0b315-8a9b-52f4-a1af-9b7b01ad8d2b","html":"<p>Si vous avez joué avec les <a href=\"https://reactjs.org/docs/hooks-intro.html\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Hooks React</a> pendant plus de quelques heures, vous avez probablement buté sur un curieux problème : utiliser <code class=\"language-text\">setInterval</code> ne <a href=\"https://stackoverflow.com/questions/53024496/state-not-updating-when-using-react-state-hook-within-setinterval\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">marche juste pas</a> comme on s’y attendrait.</p>\n<p>Pour reprendre <a href=\"https://mobile.twitter.com/ryanflorence/status/1088606583637061634\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">les mots</a> de Ryan Florence :</p>\n<blockquote>\n<p>J’ai entendu pas mal de monde dire que quand on regarde setInterval avec les hooks, on se dit que sur ce coup React doit se sentir morveux…</p>\n</blockquote>\n<p>Honnêtement, je trouve que ces personnes n’ont pas tort.  <em>C’est en effet</em> déconcertant au premier abord.</p>\n<p>Mais j’ai aussi fini par y voir non pas un défaut des Hooks, mais un décalage entre le <a href=\"/react-as-a-ui-runtime/\">modèle de programmation de React</a> et <code class=\"language-text\">setInterval</code>. Les Hooks, qui sont plus en phase avec le modèle de programmation de React que les classes, rendent ce décalage plus évident.</p>\n<p><strong>Il <em>y a</em> une manière de les faire fonctionner ensemble sans souci mais elle n’est guère intuitive.</strong></p>\n<p>Dans cet article, nous examinerons <em>comment</em> faire collaborer efficacement les intervalles et les Hooks, <em>pourquoi</em> cette solution est pertinente, et quelles <em>nouvelles</em> possibilités elle nous offre.</p>\n<hr>\n<p><strong>Avertissement : cet article se concentre sur un <em>cas pathologique</em>.  Même si l’API simplifie une centaine de cas d’utilisation, les gens parleront toujours du cas qui est devenu plus difficile.</strong></p>\n<p>Si vous ne connaissez pas les Hooks, ou ne comprenez pas pourquoi toute cette agitation, jetez plutôt un œil à <a href=\"https://medium.com/@dan_abramov/making-sense-of-react-hooks-fdbde8803889\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">cette introduction</a> et à la <a href=\"https://reactjs.org/docs/hooks-intro.html\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">documentation</a>. Cet article suppose que vous avez bossé avec les Hooks pendant plus d’une heure.</p>\n<hr>\n<h2 id=\"fais-moi-voir-le-code\"><a href=\"#fais-moi-voir-le-code\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Fais-moi voir le code</h2>\n<p>Sans plus attendre, voici un compteur qui s’incrémente à chaque seconde :</p>\n<div class=\"gatsby-highlight has-highlighted-lines\" data-language=\"jsx\"><pre class=\"language-jsx\"><code class=\"language-jsx\"><span class=\"token keyword\">import</span> React<span class=\"token punctuation\">,</span> <span class=\"token punctuation\">{</span> useState<span class=\"token punctuation\">,</span> useEffect<span class=\"token punctuation\">,</span> useRef <span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">'react'</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token keyword\">function</span> <span class=\"token function\">Counter</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">let</span> <span class=\"token punctuation\">[</span>count<span class=\"token punctuation\">,</span> setCount<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token function\">useState</span><span class=\"token punctuation\">(</span><span class=\"token number\">0</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n<span class=\"gatsby-highlight-code-line\">  <span class=\"token function\">useInterval</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span></span><span class=\"gatsby-highlight-code-line\">    <span class=\"token comment\">// Votre logique métier ici</span></span><span class=\"gatsby-highlight-code-line\">    <span class=\"token function\">setCount</span><span class=\"token punctuation\">(</span>count <span class=\"token operator\">+</span> <span class=\"token number\">1</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></span><span class=\"gatsby-highlight-code-line\">  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span> <span class=\"token number\">1000</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></span>\n  <span class=\"token keyword\">return</span> <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>h1</span><span class=\"token punctuation\">></span></span><span class=\"token punctuation\">{</span>count<span class=\"token punctuation\">}</span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>h1</span><span class=\"token punctuation\">></span></span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p><em>(Et voici une <a href=\"https://codesandbox.io/s/105x531vkq\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">démo sur CodeSandbox</a>.)</em></p>\n<p>Ce <code class=\"language-text\">useInterval</code> n’est pas un Hook fourni par React ; c’est un <a href=\"https://reactjs.org/docs/hooks-custom.html\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Hook personnalisé</a> que j’ai écrit :</p>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"language-jsx\"><code class=\"language-jsx\"><span class=\"token keyword\">import</span> React<span class=\"token punctuation\">,</span> <span class=\"token punctuation\">{</span> useState<span class=\"token punctuation\">,</span> useEffect<span class=\"token punctuation\">,</span> useRef <span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">'react'</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token keyword\">function</span> <span class=\"token function\">useInterval</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">callback<span class=\"token punctuation\">,</span> delay</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">const</span> savedCallback <span class=\"token operator\">=</span> <span class=\"token function\">useRef</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n  <span class=\"token comment\">// Se souvenir de la dernière fonction de rappel.</span>\n  <span class=\"token function\">useEffect</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    savedCallback<span class=\"token punctuation\">.</span>current <span class=\"token operator\">=</span> callback<span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n  <span class=\"token comment\">// Configurer l’intervalle.</span>\n  <span class=\"token function\">useEffect</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">function</span> <span class=\"token function\">tick</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n      savedCallback<span class=\"token punctuation\">.</span><span class=\"token function\">current</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>delay <span class=\"token operator\">!==</span> <span class=\"token keyword\">null</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n      <span class=\"token keyword\">let</span> id <span class=\"token operator\">=</span> <span class=\"token function\">setInterval</span><span class=\"token punctuation\">(</span>tick<span class=\"token punctuation\">,</span> delay<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n      <span class=\"token keyword\">return</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token function\">clearInterval</span><span class=\"token punctuation\">(</span>id<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">[</span>delay<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p><em>(Et revoici <s>la sous-préfète</s> <a href=\"https://codesandbox.io/s/105x531vkq\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">la démo CodeSandbox</a> au cas où vous l’auriez loupée plus haut.)</em></p>\n<p><strong>Mon Hook <code class=\"language-text\">useInterval</code> met en place un intervalle et le détruit après le démontage</strong> <em>(le retrait du DOM virtuel, NdT)</em>. C’est une combo de <code class=\"language-text\">setInterval</code> et <code class=\"language-text\">clearInterval</code> associée au cycle de vie du composant.</p>\n<p>Sentez-vous libres de copier-coller ça dans vos projets ou d’en faire un module npm.</p>\n<p><strong>Si vous vous fichez de savoir pourquoi ça fonctionne, vous pouvez cesser votre lecture ici ! Le reste de cet article est pour celles et ceux qui sont prêt·e·s à explorer les Hooks React plus en profondeur.</strong></p>\n<hr>\n<h2 id=\"keskispass--\"><a href=\"#keskispass--\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Keskispass ?! 🤔</h2>\n<p>Je sais ce que vous vous dites :</p>\n<blockquote>\n<p>Dan, ce code n’a aucun sens.  Qu’est-il donc arrivé à « juste du JavaScript » ?  Admets-le, React est parti en vrille avec les Hooks !</p>\n</blockquote>\n<p><strong>Je pensais pareil mais j’ai changé d’avis, et je vais changer le vôtre.</strong>  Avant d’expliquer pourquoi ce code est pertinent, je veux la ramener un peu en vous montrant ce dont il est capable.</p>\n<hr>\n<h2 id=\"pourquoi-useinterval-est-une-meilleure-api\"><a href=\"#pourquoi-useinterval-est-une-meilleure-api\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Pourquoi <code class=\"language-text\">useInterval()</code> est une meilleure API</h2>\n<p>À titre de rappel, mon Hook <code class=\"language-text\">useInterval</code> accepte une fonction et une durée :</p>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"language-jsx\"><code class=\"language-jsx\">  <span class=\"token function\">useInterval</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    <span class=\"token comment\">// ...</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span> <span class=\"token number\">1000</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>Ça ressemble beaucoup à <code class=\"language-text\">setInterval</code> :</p>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"language-jsx\"><code class=\"language-jsx\">  <span class=\"token function\">setInterval</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    <span class=\"token comment\">// ...</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span> <span class=\"token number\">1000</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p><strong>Alors pourquoi ne pas utiliser directement <code class=\"language-text\">setInterval</code> ?</strong></p>\n<p>Ce n’est sans doute pas évident au premier abord, mais la différence entre le <code class=\"language-text\">setInterval</code> que vous connaissez et mon Hook <code class=\"language-text\">useInterval</code> c’est que <strong>ses arguments sont « dynamiques »</strong>.</p>\n<p>Permettez-moi d’illustrer ça avec un exemple concret.</p>\n<hr>\n<p>Disons qu’on veut que la durée de l’intervalle soit ajustable :</p>\n<p><img src=\"/35e4f35a8585255b11c090aed9f72433/counter_delay.gif\" alt=\"Un compteur avec un champ qui ajuste la durée de l’intervalle\"></p>\n<p>Même si vous ne contrôleriez pas nécessairement la durée avec un <em>champ</em>, l’ajuster dynamiquement peut être utile—par exemple, pour ralentir le rythme de requêtes Ajax de mise à jour périodique lorsque l’utilisateur est passé sur un autre onglet.</p>\n<p>Alors comment feriez-vous ça avec un <code class=\"language-text\">setInterval</code> dans une classe ?  Moi, je me suis retrouvé avec le code suivant :</p>\n<div class=\"gatsby-highlight has-highlighted-lines\" data-language=\"jsx\"><pre class=\"language-jsx\"><code class=\"language-jsx\"><span class=\"token keyword\">class</span> <span class=\"token class-name\">Counter</span> <span class=\"token keyword\">extends</span> <span class=\"token class-name\">React<span class=\"token punctuation\">.</span>Component</span> <span class=\"token punctuation\">{</span>\n  state <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span>\n    count<span class=\"token operator\">:</span> <span class=\"token number\">0</span><span class=\"token punctuation\">,</span>\n    delay<span class=\"token operator\">:</span> <span class=\"token number\">1000</span><span class=\"token punctuation\">,</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\n\n<span class=\"gatsby-highlight-code-line\">  <span class=\"token function\">componentDidMount</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span></span><span class=\"gatsby-highlight-code-line\">    <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>interval <span class=\"token operator\">=</span> <span class=\"token function\">setInterval</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>tick<span class=\"token punctuation\">,</span> <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>state<span class=\"token punctuation\">.</span>delay<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></span><span class=\"gatsby-highlight-code-line\">  <span class=\"token punctuation\">}</span></span><span class=\"gatsby-highlight-code-line\"></span><span class=\"gatsby-highlight-code-line\">  <span class=\"token function\">componentDidUpdate</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">prevProps<span class=\"token punctuation\">,</span> prevState</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span></span><span class=\"gatsby-highlight-code-line\">    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>prevState<span class=\"token punctuation\">.</span>delay <span class=\"token operator\">!==</span> <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>state<span class=\"token punctuation\">.</span>delay<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span></span><span class=\"gatsby-highlight-code-line\">      <span class=\"token function\">clearInterval</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>interval<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></span><span class=\"gatsby-highlight-code-line\">      <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>interval <span class=\"token operator\">=</span> <span class=\"token function\">setInterval</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>tick<span class=\"token punctuation\">,</span> <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>state<span class=\"token punctuation\">.</span>delay<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></span><span class=\"gatsby-highlight-code-line\">    <span class=\"token punctuation\">}</span></span><span class=\"gatsby-highlight-code-line\">  <span class=\"token punctuation\">}</span></span><span class=\"gatsby-highlight-code-line\"></span><span class=\"gatsby-highlight-code-line\">  <span class=\"token function\">componentWillUnmount</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span></span><span class=\"gatsby-highlight-code-line\">    <span class=\"token function\">clearInterval</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>interval<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></span><span class=\"gatsby-highlight-code-line\">  <span class=\"token punctuation\">}</span></span><span class=\"gatsby-highlight-code-line\"></span><span class=\"gatsby-highlight-code-line\">  <span class=\"token function-variable function\">tick</span> <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span></span><span class=\"gatsby-highlight-code-line\">    <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span><span class=\"token function\">setState</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span></span><span class=\"gatsby-highlight-code-line\">      count<span class=\"token operator\">:</span> <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>state<span class=\"token punctuation\">.</span>count <span class=\"token operator\">+</span> <span class=\"token number\">1</span></span><span class=\"gatsby-highlight-code-line\">    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></span><span class=\"gatsby-highlight-code-line\">  <span class=\"token punctuation\">}</span></span>\n  <span class=\"token function-variable function\">handleDelayChange</span> <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\">e</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span><span class=\"token function\">setState</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span> delay<span class=\"token operator\">:</span> <span class=\"token function\">Number</span><span class=\"token punctuation\">(</span>e<span class=\"token punctuation\">.</span>target<span class=\"token punctuation\">.</span>value<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span>\n\n  <span class=\"token function\">render</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">return</span> <span class=\"token punctuation\">(</span>\n      <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span></span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\"></span>\n<span class=\"token plain-text\">        </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>h1</span><span class=\"token punctuation\">></span></span><span class=\"token punctuation\">{</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>state<span class=\"token punctuation\">.</span>count<span class=\"token punctuation\">}</span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>h1</span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\"></span>\n<span class=\"token plain-text\">        </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>input</span> <span class=\"token attr-name\">value</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>state<span class=\"token punctuation\">.</span>delay<span class=\"token punctuation\">}</span></span> <span class=\"token attr-name\">onChange</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>handleDelayChange<span class=\"token punctuation\">}</span></span> <span class=\"token punctuation\">/></span></span><span class=\"token plain-text\"></span>\n<span class=\"token plain-text\">      </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span></span><span class=\"token punctuation\">></span></span>\n    <span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p><em>(Et voilà la <a href=\"https://codesandbox.io/s/mz20m600mp\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">démo sur CodeSandbox</a>.)</em></p>\n<p>C’est pas si mal !</p>\n<p>Et à quoi ressemble la version basée Hook ?</p>\n<p><font size=\"50\">🥁🥁🥁</font></p>\n<div class=\"gatsby-highlight has-highlighted-lines\" data-language=\"jsx\"><pre class=\"language-jsx\"><code class=\"language-jsx\"><span class=\"token keyword\">function</span> <span class=\"token function\">Counter</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">let</span> <span class=\"token punctuation\">[</span>count<span class=\"token punctuation\">,</span> setCount<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token function\">useState</span><span class=\"token punctuation\">(</span><span class=\"token number\">0</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token keyword\">let</span> <span class=\"token punctuation\">[</span>delay<span class=\"token punctuation\">,</span> setDelay<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token function\">useState</span><span class=\"token punctuation\">(</span><span class=\"token number\">1000</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n<span class=\"gatsby-highlight-code-line\">  <span class=\"token function\">useInterval</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span></span><span class=\"gatsby-highlight-code-line\">    <span class=\"token comment\">// Votre logique métier ici</span></span><span class=\"gatsby-highlight-code-line\">    <span class=\"token function\">setCount</span><span class=\"token punctuation\">(</span>count <span class=\"token operator\">+</span> <span class=\"token number\">1</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></span><span class=\"gatsby-highlight-code-line\">  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span> delay<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></span>\n  <span class=\"token keyword\">function</span> <span class=\"token function\">handleDelayChange</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">e</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token function\">setDelay</span><span class=\"token punctuation\">(</span><span class=\"token function\">Number</span><span class=\"token punctuation\">(</span>e<span class=\"token punctuation\">.</span>target<span class=\"token punctuation\">.</span>value<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span>\n\n  <span class=\"token keyword\">return</span> <span class=\"token punctuation\">(</span>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span></span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\"></span>\n<span class=\"token plain-text\">      </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>h1</span><span class=\"token punctuation\">></span></span><span class=\"token punctuation\">{</span>count<span class=\"token punctuation\">}</span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>h1</span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\"></span>\n<span class=\"token plain-text\">      </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>input</span> <span class=\"token attr-name\">value</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span>delay<span class=\"token punctuation\">}</span></span> <span class=\"token attr-name\">onChange</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span>handleDelayChange<span class=\"token punctuation\">}</span></span> <span class=\"token punctuation\">/></span></span><span class=\"token plain-text\"></span>\n<span class=\"token plain-text\">    </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span></span><span class=\"token punctuation\">></span></span>\n  <span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p><em>(Et sa <a href=\"https://codesandbox.io/s/329jy81rlm\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">démo sur CodeSandbox</a>.)</em></p>\n<p>Et ouais, <em>c’est tout</em>.</p>\n<p>Contrairement à la version basée classe, il n’y a pas de montée en complexité afin « d’améliorer » notre exemple de Hook pour disposer d’une durée ajustable dynamiquement :</p>\n<div class=\"gatsby-highlight has-highlighted-lines\" data-language=\"jsx\"><pre class=\"language-jsx\"><code class=\"language-jsx\">  <span class=\"token comment\">// Durée constante</span>\n  <span class=\"token function\">useInterval</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    <span class=\"token function\">setCount</span><span class=\"token punctuation\">(</span>count <span class=\"token operator\">+</span> <span class=\"token number\">1</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"gatsby-highlight-code-line\">  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span> <span class=\"token number\">1000</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></span>\n  <span class=\"token comment\">// Durée ajustable</span>\n  <span class=\"token function\">useInterval</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    <span class=\"token function\">setCount</span><span class=\"token punctuation\">(</span>count <span class=\"token operator\">+</span> <span class=\"token number\">1</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"gatsby-highlight-code-line\">  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span> delay<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></span></code></pre></div>\n<p>Quand le Hook <code class=\"language-text\">useInterval</code> voit une durée différente, il reconfigure l’intervalle.</p>\n<p><strong>Au lieu d’écrire du code qui <em>crée</em> et <em>efface</em> l’intervalle, je peux <em>déclarer</em> un intervalle avec une durée particulière—et notre Hook <code class=\"language-text\">useInterval</code> s’occupe du reste.</strong></p>\n<p>Et si je voulais mettre temporairement mon intervalle <em>en pause</em> ?  Je peux le faire avec un état :</p>\n<div class=\"gatsby-highlight has-highlighted-lines\" data-language=\"jsx\"><pre class=\"language-jsx\"><code class=\"language-jsx\">  <span class=\"token keyword\">const</span> <span class=\"token punctuation\">[</span>delay<span class=\"token punctuation\">,</span> setDelay<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token function\">useState</span><span class=\"token punctuation\">(</span><span class=\"token number\">1000</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token keyword\">const</span> <span class=\"token punctuation\">[</span>isRunning<span class=\"token punctuation\">,</span> setIsRunning<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token function\">useState</span><span class=\"token punctuation\">(</span><span class=\"token boolean\">true</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n  <span class=\"token function\">useInterval</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    <span class=\"token function\">setCount</span><span class=\"token punctuation\">(</span>count <span class=\"token operator\">+</span> <span class=\"token number\">1</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"gatsby-highlight-code-line\">  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span> isRunning <span class=\"token operator\">?</span> delay <span class=\"token operator\">:</span> <span class=\"token keyword\">null</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></span></code></pre></div>\n<p><em>(Voici la <a href=\"https://codesandbox.io/s/l240mp2pm7\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">démo</a> !)</em></p>\n<p>C’est le genre de truc sur les Hooks qui me redonne la pêche en React.  On peut enrober des APIs impératives existantes et créer des APIs déclaratives qui expriment plus lisiblement notre intention.  Tout comme avec le rendu, nous pouvons <strong>décrire le process dans toute sa temporalité simultanément</strong> plutôt que d’émettre précautionneusement toute une série de commandes pour le manipuler.</p>\n<hr>\n<p>J’espère que ça vous a convaincus que le Hook <code class=\"language-text\">useInterval()</code> est une plus chouette API—au moins quand on s’en sert au sein d’un composant.</p>\n<p><strong>Mais pourquoi est-il pénible d’utiliser <code class=\"language-text\">setInterval()</code> et <code class=\"language-text\">clearInterval()</code> avec les Hooks ?</strong>  Revenons sur notre exemple de compteur pour tenter de l’implémenter à la main.</p>\n<hr>\n<h2 id=\"première-tentative\"><a href=\"#premi%C3%A8re-tentative\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Première tentative</h2>\n<p>Je vais commencer avec un exemple simple qui fait juste le rendu de l’état initial :</p>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"language-jsx\"><code class=\"language-jsx\"><span class=\"token keyword\">function</span> <span class=\"token function\">Counter</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">const</span> <span class=\"token punctuation\">[</span>count<span class=\"token punctuation\">,</span> setCount<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token function\">useState</span><span class=\"token punctuation\">(</span><span class=\"token number\">0</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token keyword\">return</span> <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>h1</span><span class=\"token punctuation\">></span></span><span class=\"token punctuation\">{</span>count<span class=\"token punctuation\">}</span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>h1</span><span class=\"token punctuation\">></span></span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Ensuite, je veux un intervalle qui l’incrémente à chaque seconde.  C’est un <a href=\"https://reactjs.org/docs/hooks-effect.html#effects-with-cleanup\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">effet de bord qui devra se nettoyer</a> alors je vais utiliser <code class=\"language-text\">useEffect()</code> et renvoyer la fonction de nettoyage :</p>\n<div class=\"gatsby-highlight has-highlighted-lines\" data-language=\"jsx\"><pre class=\"language-jsx\"><code class=\"language-jsx\"><span class=\"token keyword\">function</span> <span class=\"token function\">Counter</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">let</span> <span class=\"token punctuation\">[</span>count<span class=\"token punctuation\">,</span> setCount<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token function\">useState</span><span class=\"token punctuation\">(</span><span class=\"token number\">0</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n<span class=\"gatsby-highlight-code-line\">  <span class=\"token function\">useEffect</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span></span><span class=\"gatsby-highlight-code-line\">    <span class=\"token keyword\">let</span> id <span class=\"token operator\">=</span> <span class=\"token function\">setInterval</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span></span><span class=\"gatsby-highlight-code-line\">      <span class=\"token function\">setCount</span><span class=\"token punctuation\">(</span>count <span class=\"token operator\">+</span> <span class=\"token number\">1</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></span><span class=\"gatsby-highlight-code-line\">    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span> <span class=\"token number\">1000</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></span><span class=\"gatsby-highlight-code-line\">    <span class=\"token keyword\">return</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token function\">clearInterval</span><span class=\"token punctuation\">(</span>id<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></span><span class=\"gatsby-highlight-code-line\">  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></span>\n  <span class=\"token keyword\">return</span> <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>h1</span><span class=\"token punctuation\">></span></span><span class=\"token punctuation\">{</span>count<span class=\"token punctuation\">}</span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>h1</span><span class=\"token punctuation\">></span></span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p><em>(Voir la <a href=\"https://codesandbox.io/s/7wlxk1k87j\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">démo sur CodeSandbox</a>.)</em></p>\n<p>Ça semble assez simple ?  Ça marche pas trop mal.</p>\n<p><strong>Pourtant, ce code a un comportement étrange.</strong></p>\n<p>Par défaut, React ré-applique les effets à chaque rendu.  C’est volontaire car ça permet d’éviter <a href=\"https://reactjs.org/docs/hooks-effect.html#explanation-why-effects-run-on-each-update\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">toute une catégorie de bugs</a> qu’on trouve dans les composants React à base de classes.</p>\n<p>Ce comportement est généralement souhaitable car de nombreuses APIs d’inscription peuvent facilement retirer l’ancien écouteur et ajouter le nouveau à tout moment.  Hélas, <code class=\"language-text\">setInterval</code> n’est pas de celles-ci.  Quand nous appelons <code class=\"language-text\">clearInterval</code> et <code class=\"language-text\">setInterval</code>, leur planification se décale.  Si nous refaisons un rendu et ré-appliquons les effets trop souvent, l’intervalle n’aura jamais l’opportunité de se déclencher !</p>\n<p>On peut voir ce bug en refaisant un rendu de notre composant au sein d’un intervalle <em>plus court</em> :</p>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"language-jsx\"><code class=\"language-jsx\"><span class=\"token function\">setInterval</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n  <span class=\"token comment\">// Refait le rendu et ré-applique les effets de Counter,</span>\n  <span class=\"token comment\">// ce qui entraîne un clearInterval() et un setInterval()</span>\n  <span class=\"token comment\">// avant même que l’intervalle ne se déclenche.</span>\n  ReactDOM<span class=\"token punctuation\">.</span><span class=\"token function\">render</span><span class=\"token punctuation\">(</span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span><span class=\"token class-name\">Counter</span></span> <span class=\"token punctuation\">/></span></span><span class=\"token punctuation\">,</span> rootElement<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span> <span class=\"token number\">100</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p><em>(Voir une <a href=\"https://codesandbox.io/s/9j86r218y4\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">démo</a> de ce bug.)</em></p>\n<hr>\n<h2 id=\"deuxième-tentative\"><a href=\"#deuxi%C3%A8me-tentative\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Deuxième tentative</h2>\n<p>Vous savez peut-être que <code class=\"language-text\">useEffect()</code> nous permet de <a href=\"https://reactjs.org/docs/hooks-effect.html#tip-optimizing-performance-by-skipping-effects\" target=\"_blank\" rel=\"nofollow noopener noreferrer\"><em>refuser</em></a> que nos effets soient ré-appliqués.  On peut préciser un tableau de dépendances comme second argument, et React ne ré-exécutera notre effet que si quelque chose change dans ce tableau :</p>\n<div class=\"gatsby-highlight has-highlighted-lines\" data-language=\"jsx\"><pre class=\"language-jsx\"><code class=\"language-jsx\"><span class=\"token function\">useEffect</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n  document<span class=\"token punctuation\">.</span>title <span class=\"token operator\">=</span> <span class=\"token template-string\"><span class=\"token template-punctuation string\">`</span><span class=\"token string\">Vous avez cliqué </span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${</span>count<span class=\"token interpolation-punctuation punctuation\">}</span></span><span class=\"token string\"> fois</span><span class=\"token template-punctuation string\">`</span></span><span class=\"token punctuation\">;</span>\n<span class=\"gatsby-highlight-code-line\"><span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">[</span>count<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></span></code></pre></div>\n<p>Quand nous voulons exécuter un effet <em>seulement</em> au montage, et le nettoyer au démontage, on peut passer un tableau de dépendances vides <code class=\"language-text\">[]</code>.</p>\n<p>Cependant, c’est souvent la cause d’erreurs si vous n’êtes pas bien à l’aise avec les fermetures lexicales <em>(closures, NdT)</em> en JavaScript.  Nous allons faire cette erreur dès maintenant ! (Notez qu’on est en train de construire une <a href=\"https://github.com/facebook/react/pull/14636\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">règle de linter</a> conçue pour mettre en évidence ce type de bugs le plus tôt possible, mais elle n’est pas encore tout à fait prête.)</p>\n<p>Avec notre première tentative, notre problème venait du fait que la ré-exécution des effets effaçait trop tôt notre timer.  On peut tenter de corriger ça en ne les ré-exécutant jamais :</p>\n<div class=\"gatsby-highlight has-highlighted-lines\" data-language=\"jsx\"><pre class=\"language-jsx\"><code class=\"language-jsx\"><span class=\"token keyword\">function</span> <span class=\"token function\">Counter</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">let</span> <span class=\"token punctuation\">[</span>count<span class=\"token punctuation\">,</span> setCount<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token function\">useState</span><span class=\"token punctuation\">(</span><span class=\"token number\">0</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n  <span class=\"token function\">useEffect</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">let</span> id <span class=\"token operator\">=</span> <span class=\"token function\">setInterval</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n      <span class=\"token function\">setCount</span><span class=\"token punctuation\">(</span>count <span class=\"token operator\">+</span> <span class=\"token number\">1</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span> <span class=\"token number\">1000</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">return</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token function\">clearInterval</span><span class=\"token punctuation\">(</span>id<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"gatsby-highlight-code-line\">  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">[</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></span>\n  <span class=\"token keyword\">return</span> <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>h1</span><span class=\"token punctuation\">></span></span><span class=\"token punctuation\">{</span>count<span class=\"token punctuation\">}</span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>h1</span><span class=\"token punctuation\">></span></span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Sauf que voilà, maintenant notre compteur monte à 1 et ne bouge plus. (<a href=\"https://codesandbox.io/s/jj0mk6y683\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Voir le bug en action</a>.)</p>\n<p>Que s’est-il passé ?</p>\n<p><strong>Le problème, c’est que <code class=\"language-text\">useEffect</code> capture la valeur de <code class=\"language-text\">count</code> issue du premier rendu.</strong>  Il est égal à <code class=\"language-text\">0</code>.  On ne ré-applique jamais l’effet, alors la fermeture lexicale de <code class=\"language-text\">setInterval</code> référence toujours le <code class=\"language-text\">count</code> du premier rendu, et <code class=\"language-text\">count + 1</code> est toujours <code class=\"language-text\">1</code>. Oups !</p>\n<p><strong>J’entends vos dents grincer d’ici.  Les hooks sont énervants, pas vrai ?</strong></p>\n<p><a href=\"https://codesandbox.io/s/j379jxrzjy\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Une des manières</a> de corriger ça serait de remplacer <code class=\"language-text\">setCount(count + 1)</code> par sa forme « fonction de mise à jour » <code class=\"language-text\">setCount(c =&gt; c + 1)</code>.  Elle pourra ainsi toujours lire l’état à jour dans cette variable.  Mais ça ne nous aiderait pas à lire des props à jour, par exemple.</p>\n<p><a href=\"https://codesandbox.io/s/00o9o95jyv\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Un autre correctif</a> consisterait à utiliser <a href=\"https://reactjs.org/docs/hooks-reference.html#usereducer\" target=\"_blank\" rel=\"nofollow noopener noreferrer\"><code class=\"language-text\">useReducer()</code></a>.  Cette approche nous donne une meilleure flexibilité.  Au sein du réducteur, vous avez accès tant à l’état courant qu’aux props à jour.  La fonction <code class=\"language-text\">dispatch</code> elle-même ne change jamais, alors on peut y balancer des données depuis n’importe quelle fermeture lexicale.  <code class=\"language-text\">useReducer()</code> est toutefois limité en ce qu’il ne permet pas d’émettre des effets de bord. (Ceci dit, vous pouvez renvoyer un nouvel état—qui pourrait déclencher un effet.)</p>\n<p><strong>Mais pourquoi ça devient si compliqué ?</strong></p>\n<hr>\n<h2 id=\"le-décalage-dimpédance\"><a href=\"#le-d%C3%A9calage-dimp%C3%A9dance\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Le décalage d’impédance</h2>\n<p>On emploie parfois ce terme, et <a href=\"https://haacked.com/archive/2004/06/15/impedance-mismatch.aspx/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Phil Haack</a> l’explique ainsi :</p>\n<blockquote>\n<p>On pourrait dire que les Bases de données viennent de Mars et les Objets de Vénus.  Les bases de données n’ont pas de correspondance naturelle aux modèles objets.  Ça revient en fait à essayer de faire coller les pôles Nord de deux aimants.</p>\n</blockquote>\n<p>Notre « décalage d’impédance » n’est pas ici entre les Bases de Données et les Objets.  Il survient entre le modèle de programmation de React et l’API impérative <code class=\"language-text\">setInterval</code>.</p>\n<p><strong>Un composant React peut être monté pendant un bout de temps et passer par de nombreux états distincts, mais son résultat de rendu est censé <em>tous les décrire d’un coup.</em></strong></p>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"language-jsx\"><code class=\"language-jsx\">  <span class=\"token comment\">// Décrit tous les rendus possibles</span>\n  <span class=\"token keyword\">return</span> <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>h1</span><span class=\"token punctuation\">></span></span><span class=\"token punctuation\">{</span>count<span class=\"token punctuation\">}</span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>h1</span><span class=\"token punctuation\">></span></span></code></pre></div>\n<p>Les Hooks nous permettent d’appliquer la même approche déclarative pour les effets :</p>\n<div class=\"gatsby-highlight has-highlighted-lines\" data-language=\"jsx\"><pre class=\"language-jsx\"><code class=\"language-jsx\">  <span class=\"token comment\">// Décrit tous les états d’intervalle</span>\n  <span class=\"token function\">useInterval</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    <span class=\"token function\">setCount</span><span class=\"token punctuation\">(</span>count <span class=\"token operator\">+</span> <span class=\"token number\">1</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"gatsby-highlight-code-line\">  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span> isRunning <span class=\"token operator\">?</span> delay <span class=\"token operator\">:</span> <span class=\"token keyword\">null</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></span></code></pre></div>\n<p>On ne <em>configure</em> pas l’intervalle, mais on définit <em>si</em> il est actif, et avec quelle durée.  Notre Hook s’occupe de la réalisation.  Un processus continu est ici décrit en termes discrets.</p>\n<p><strong>À l’inverse, <code class=\"language-text\">setInterval</code> ne décrit pas un processus dans le temps—une fois l’intervalle configuré, vous ne pouvez rien y changer, à part l’annuler.</strong></p>\n<p>Voilà le décalage entre le modèle de React et l’API <code class=\"language-text\">setInterval</code>.</p>\n<hr>\n<p>Les props et l’état des composants React peuvent changer.  React refera leur rendu et « oubliera » tout du résultat du rendu précédent.  Ce dernier n’a plus d’intérêt.</p>\n<p>Le Hook <code class=\"language-text\">useEffect()</code> « oublie » le rendu précédent, lui aussi.  Il nettoie l’effet précédent et configure l’effet suivant.  Cet effet suivant porte dans sa fermeture lexicale les props et l’état à jour.  C’est pourquoi notre <a href=\"https://codesandbox.io/s/7wlxk1k87j\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">première tentative</a> marche pour les cas simples.</p>\n<p><strong>Mais <code class=\"language-text\">setInterval</code> « n’oublie » rien.</strong>  Il référencera pour toujours les anciennes valeurs des props et de l’état, à moins que vous ne le remplaciez—ce que vous ne pouvez pas faire sans réinitialiser la planification.</p>\n<p>À moins que…?</p>\n<hr>\n<h2 id=\"les-refs-à-la-rescousse-\"><a href=\"#les-refs-%C3%A0-la-rescousse-\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Les refs à la rescousse !</h2>\n<!-- RESUME -->\n<p>Le problème se résume à ceci :</p>\n<ul>\n<li>On appelle <code class=\"language-text\">setInterval(callback1, delay)</code> avec le <code class=\"language-text\">callback1</code> du premier rendu.</li>\n<li>On a <code class=\"language-text\">callback2</code> du rendu suivant, dont la fermeture lexicale contient les props et l’état à jour.</li>\n<li>Mais on ne peut pas remplacer un intervalle existant sans réinitialiser sa planification !</li>\n</ul>\n<p><strong>Alors si on ne remplaçait pas du tout l’intervalle, mais qu’on introduisait plutôt une variable modifiable <code class=\"language-text\">savedCallback</code> qui pointerait vers la fonction de rappel <em>la plus récente</em> pour l’intervalle ?</strong></p>\n<p>On entrevoit maintenant la solution :</p>\n<ul>\n<li>On appelle <code class=\"language-text\">setInterval(fn, delay)</code>, avec <code class=\"language-text\">fn</code> qui appelle <code class=\"language-text\">savedCallback</code>.</li>\n<li>On fait pointer <code class=\"language-text\">savedCallback</code> sur <code class=\"language-text\">callback1</code> après le premier rendu.</li>\n<li>On fait pointer <code class=\"language-text\">savedCallback</code> sur <code class=\"language-text\">callback2</code> après le rendu suivant.</li>\n<li>???</li>\n<li>FORTUNE ET GLOIRE</li>\n</ul>\n<p>Ce <code class=\"language-text\">savedCallback</code> modifiable doit pouvoir « persister » d’un rendu à l’autre.  Il ne peut donc pas s’agir d’une variable classique.  On veut quelque chose qui se comporte plus comme un champ d’instance.</p>\n<p><a href=\"https://reactjs.org/docs/hooks-faq.html#is-there-something-like-instance-variables\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Comme on peut le voir dans la FAQ des Hooks</a>, <code class=\"language-text\">useRef()</code> nous fournit exactement ça :</p>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"language-jsx\"><code class=\"language-jsx\">  <span class=\"token keyword\">const</span> savedCallback <span class=\"token operator\">=</span> <span class=\"token function\">useRef</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token comment\">// { current: null }</span></code></pre></div>\n<p><em>(Vous connaissez peut-être les <a href=\"https://reactjs.org/docs/refs-and-the-dom.html\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">refs DOM</a> de React.  Les Hooks utilisent le même concept pour garder sous la main des valeurs modifiables.  Une ref est comme une « boîte » dans laquelle vous pouvez mettre ce qui vous chante.)</em></p>\n<p><code class=\"language-text\">useRef()</code> renvoie un objet brut avec une propriété modifiable <code class=\"language-text\">current</code>, partagée d’un rendu à l’autre.  On peut y sauvegarder la fonction de rappel <em>la plus récente</em> pour l’intervalle :</p>\n<div class=\"gatsby-highlight has-highlighted-lines\" data-language=\"jsx\"><pre class=\"language-jsx\"><code class=\"language-jsx\">  <span class=\"token keyword\">function</span> <span class=\"token function\">callback</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token comment\">// Ici on a accès aux props et à l’état à jour, etc.</span>\n    <span class=\"token function\">setCount</span><span class=\"token punctuation\">(</span>count <span class=\"token operator\">+</span> <span class=\"token number\">1</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span>\n\n  <span class=\"token comment\">// Après chaque rendu, on sauve la fonction de rappel</span>\n  <span class=\"token comment\">// à jour dans notre ref.</span>\n<span class=\"gatsby-highlight-code-line\">  <span class=\"token function\">useEffect</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span></span>    savedCallback<span class=\"token punctuation\">.</span>current <span class=\"token operator\">=</span> callback<span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>Après quoi on peut la lire et l’appeler au sein de notre intervalle :</p>\n<div class=\"gatsby-highlight has-highlighted-lines\" data-language=\"jsx\"><pre class=\"language-jsx\"><code class=\"language-jsx\">  <span class=\"token function\">useEffect</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">function</span> <span class=\"token function\">tick</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n<span class=\"gatsby-highlight-code-line\">      savedCallback<span class=\"token punctuation\">.</span><span class=\"token function\">current</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></span>    <span class=\"token punctuation\">}</span>\n\n    <span class=\"token keyword\">let</span> id <span class=\"token operator\">=</span> <span class=\"token function\">setInterval</span><span class=\"token punctuation\">(</span>tick<span class=\"token punctuation\">,</span> <span class=\"token number\">1000</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">return</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token function\">clearInterval</span><span class=\"token punctuation\">(</span>id<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"gatsby-highlight-code-line\">  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">[</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></span></code></pre></div>\n<p>Grâce au <code class=\"language-text\">[]</code>, notre effet n’est jamais ré-exécuté, du coup l’intervalle n’est pas réinitialisé.  Néanmoins, grâce à la ref <code class=\"language-text\">savedCallback</code>, nous pouvons toujours lire la fonction de rappel définie lors du dernier rendu, et l’appeler à chaque tic de l’intervalle.</p>\n<p>Voici la solution complète qui fonctionne :</p>\n<div class=\"gatsby-highlight has-highlighted-lines\" data-language=\"jsx\"><pre class=\"language-jsx\"><code class=\"language-jsx\"><span class=\"token keyword\">function</span> <span class=\"token function\">Counter</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">const</span> <span class=\"token punctuation\">[</span>count<span class=\"token punctuation\">,</span> setCount<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token function\">useState</span><span class=\"token punctuation\">(</span><span class=\"token number\">0</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token keyword\">const</span> savedCallback <span class=\"token operator\">=</span> <span class=\"token function\">useRef</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n  <span class=\"token keyword\">function</span> <span class=\"token function\">callback</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token function\">setCount</span><span class=\"token punctuation\">(</span>count <span class=\"token operator\">+</span> <span class=\"token number\">1</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span>\n\n  <span class=\"token function\">useEffect</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n<span class=\"gatsby-highlight-code-line\">    savedCallback<span class=\"token punctuation\">.</span>current <span class=\"token operator\">=</span> callback<span class=\"token punctuation\">;</span></span>  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n  <span class=\"token function\">useEffect</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">function</span> <span class=\"token function\">tick</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n<span class=\"gatsby-highlight-code-line\">      savedCallback<span class=\"token punctuation\">.</span><span class=\"token function\">current</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></span>    <span class=\"token punctuation\">}</span>\n\n    <span class=\"token keyword\">let</span> id <span class=\"token operator\">=</span> <span class=\"token function\">setInterval</span><span class=\"token punctuation\">(</span>tick<span class=\"token punctuation\">,</span> <span class=\"token number\">1000</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">return</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token function\">clearInterval</span><span class=\"token punctuation\">(</span>id<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">[</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n  <span class=\"token keyword\">return</span> <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>h1</span><span class=\"token punctuation\">></span></span><span class=\"token punctuation\">{</span>count<span class=\"token punctuation\">}</span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>h1</span><span class=\"token punctuation\">></span></span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p><em>(Voir la <a href=\"https://codesandbox.io/s/3499qqr565\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">démo sur CodeSandbox</a>.)</em></p>\n<hr>\n<h2 id=\"extraire-un-hook\"><a href=\"#extraire-un-hook\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Extraire un Hook</h2>\n<p>J’avoue, le code ci-dessus peut être déroutant.  Ça tord un peu le cerveau de mélanger des paradigmes opposés.  Il existe aussi un risque de mettre le bazar avec les refs modifiables.</p>\n<p><strong>Je trouve que les Hooks fournissent des primitives de plus bas niveau que les classes—mais leur beauté réside en ce qu’ils nous permettent de les composer pour créer de meilleures abstractions déclaratives.</strong></p>\n<p>Idéalement, j’aimerais juste pouvoir écrire :</p>\n<div class=\"gatsby-highlight has-highlighted-lines\" data-language=\"jsx\"><pre class=\"language-jsx\"><code class=\"language-jsx\"><span class=\"token keyword\">function</span> <span class=\"token function\">Counter</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">const</span> <span class=\"token punctuation\">[</span>count<span class=\"token punctuation\">,</span> setCount<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token function\">useState</span><span class=\"token punctuation\">(</span><span class=\"token number\">0</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n<span class=\"gatsby-highlight-code-line\">  <span class=\"token function\">useInterval</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span></span><span class=\"gatsby-highlight-code-line\">    <span class=\"token function\">setCount</span><span class=\"token punctuation\">(</span>count <span class=\"token operator\">+</span> <span class=\"token number\">1</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></span><span class=\"gatsby-highlight-code-line\">  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span> <span class=\"token number\">1000</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></span>\n  <span class=\"token keyword\">return</span> <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>h1</span><span class=\"token punctuation\">></span></span><span class=\"token punctuation\">{</span>count<span class=\"token punctuation\">}</span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>h1</span><span class=\"token punctuation\">></span></span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Je vais copier-coller le corps de mon mécanisme de refs dans un Hook personnalisé :</p>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"language-jsx\"><code class=\"language-jsx\"><span class=\"token keyword\">function</span> <span class=\"token function\">useInterval</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">callback</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">const</span> savedCallback <span class=\"token operator\">=</span> <span class=\"token function\">useRef</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n  <span class=\"token function\">useEffect</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    savedCallback<span class=\"token punctuation\">.</span>current <span class=\"token operator\">=</span> callback<span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n  <span class=\"token function\">useEffect</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">function</span> <span class=\"token function\">tick</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n      savedCallback<span class=\"token punctuation\">.</span><span class=\"token function\">current</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n\n    <span class=\"token keyword\">let</span> id <span class=\"token operator\">=</span> <span class=\"token function\">setInterval</span><span class=\"token punctuation\">(</span>tick<span class=\"token punctuation\">,</span> <span class=\"token number\">1000</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">return</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token function\">clearInterval</span><span class=\"token punctuation\">(</span>id<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">[</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Pour le moment, ma durée de <code class=\"language-text\">1000</code> est codée en dur.  J’aimerais en faire un argument :</p>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"language-jsx\"><code class=\"language-jsx\"><span class=\"token keyword\">function</span> <span class=\"token function\">useInterval</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">callback<span class=\"token punctuation\">,</span> delay</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span></code></pre></div>\n<p>Je vais l’utiliser pour configurer l’intervalle :</p>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"language-jsx\"><code class=\"language-jsx\">    <span class=\"token keyword\">let</span> id <span class=\"token operator\">=</span> <span class=\"token function\">setInterval</span><span class=\"token punctuation\">(</span>tick<span class=\"token punctuation\">,</span> delay<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>À présent que le <code class=\"language-text\">delay</code> peut changer d’un rendu à l’autre, j’ai besoin de le déclarer dans les dépendances de mon effet d’intervalle :</p>\n<div class=\"gatsby-highlight has-highlighted-lines\" data-language=\"jsx\"><pre class=\"language-jsx\"><code class=\"language-jsx\">  <span class=\"token function\">useEffect</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">function</span> <span class=\"token function\">tick</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n      savedCallback<span class=\"token punctuation\">.</span><span class=\"token function\">current</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n\n    <span class=\"token keyword\">let</span> id <span class=\"token operator\">=</span> <span class=\"token function\">setInterval</span><span class=\"token punctuation\">(</span>tick<span class=\"token punctuation\">,</span> delay<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">return</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token function\">clearInterval</span><span class=\"token punctuation\">(</span>id<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"gatsby-highlight-code-line\">  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">[</span>delay<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></span></code></pre></div>\n<p>Attendez une minute, on ne voulait pas justement éviter de réinitialiser l’effet d’intervalle, en lui passant expressément <code class=\"language-text\">[]</code> pour cette raison ?  Pas exacte­ment.  On voulait juste éviter de le réinitialiser quand <em>la fonction de rappel</em> changeait.  Mais si <code class=\"language-text\">delay</code> change, on <em>veut</em> redémarrer le timer !</p>\n<p>Voyons si notre code fonctionne :</p>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"language-jsx\"><code class=\"language-jsx\"><span class=\"token keyword\">function</span> <span class=\"token function\">Counter</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">const</span> <span class=\"token punctuation\">[</span>count<span class=\"token punctuation\">,</span> setCount<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token function\">useState</span><span class=\"token punctuation\">(</span><span class=\"token number\">0</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n  <span class=\"token function\">useInterval</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    <span class=\"token function\">setCount</span><span class=\"token punctuation\">(</span>count <span class=\"token operator\">+</span> <span class=\"token number\">1</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span> <span class=\"token number\">1000</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n  <span class=\"token keyword\">return</span> <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>h1</span><span class=\"token punctuation\">></span></span><span class=\"token punctuation\">{</span>count<span class=\"token punctuation\">}</span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>h1</span><span class=\"token punctuation\">></span></span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token keyword\">function</span> <span class=\"token function\">useInterval</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">callback<span class=\"token punctuation\">,</span> delay</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">const</span> savedCallback <span class=\"token operator\">=</span> <span class=\"token function\">useRef</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n  <span class=\"token function\">useEffect</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    savedCallback<span class=\"token punctuation\">.</span>current <span class=\"token operator\">=</span> callback<span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n  <span class=\"token function\">useEffect</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">function</span> <span class=\"token function\">tick</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n      savedCallback<span class=\"token punctuation\">.</span><span class=\"token function\">current</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n\n    <span class=\"token keyword\">let</span> id <span class=\"token operator\">=</span> <span class=\"token function\">setInterval</span><span class=\"token punctuation\">(</span>tick<span class=\"token punctuation\">,</span> delay<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">return</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token function\">clearInterval</span><span class=\"token punctuation\">(</span>id<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">[</span>delay<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p><em>(Essayez donc sur <a href=\"https://codesandbox.io/s/xvyl15375w\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">CodeSandbox</a>.)</em></p>\n<p>Ça marche ! On peut maintenant faire un <code class=\"language-text\">useInterval()</code> dans n’importe quel composant sans avoir à trop penser aux détails de son implémentation.</p>\n<h2 id=\"bonus--mettre-lintervalle-en-pause\"><a href=\"#bonus--mettre-lintervalle-en-pause\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Bonus : mettre l’intervalle en pause</h2>\n<p>Disons que nous voulons pouvoir mettre l’intervalle en pause en passant <code class=\"language-text\">null</code> comme <code class=\"language-text\">delay</code> :</p>\n<div class=\"gatsby-highlight has-highlighted-lines\" data-language=\"jsx\"><pre class=\"language-jsx\"><code class=\"language-jsx\">  <span class=\"token keyword\">const</span> <span class=\"token punctuation\">[</span>delay<span class=\"token punctuation\">,</span> setDelay<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token function\">useState</span><span class=\"token punctuation\">(</span><span class=\"token number\">1000</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token keyword\">const</span> <span class=\"token punctuation\">[</span>isRunning<span class=\"token punctuation\">,</span> setIsRunning<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token function\">useState</span><span class=\"token punctuation\">(</span><span class=\"token boolean\">true</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n  <span class=\"token function\">useInterval</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    <span class=\"token function\">setCount</span><span class=\"token punctuation\">(</span>count <span class=\"token operator\">+</span> <span class=\"token number\">1</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"gatsby-highlight-code-line\">  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span> isRunning <span class=\"token operator\">?</span> delay <span class=\"token operator\">:</span> <span class=\"token keyword\">null</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></span></code></pre></div>\n<p>Comment implémenter ça ? La réponse est simple : en ne configurant pas l’intervalle.</p>\n<div class=\"gatsby-highlight has-highlighted-lines\" data-language=\"jsx\"><pre class=\"language-jsx\"><code class=\"language-jsx\">  <span class=\"token function\">useEffect</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">function</span> <span class=\"token function\">tick</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n      savedCallback<span class=\"token punctuation\">.</span><span class=\"token function\">current</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n\n<span class=\"gatsby-highlight-code-line\">    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>delay <span class=\"token operator\">!==</span> <span class=\"token keyword\">null</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span></span>      <span class=\"token keyword\">let</span> id <span class=\"token operator\">=</span> <span class=\"token function\">setInterval</span><span class=\"token punctuation\">(</span>tick<span class=\"token punctuation\">,</span> delay<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n      <span class=\"token keyword\">return</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token function\">clearInterval</span><span class=\"token punctuation\">(</span>id<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">[</span>delay<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p><em>(Voir la <a href=\"https://codesandbox.io/s/l240mp2pm7\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">démo sur CodeSandbox</a>.)</em></p>\n<p>Et c’est tout.  Ce code gère toutes les transitions possibles : changement de durée, pause, reprise de l’intervalle.  L’API <code class=\"language-text\">useEffect()</code> nous demande de consacrer un plus gros effort en amont à la description de la mise en place et du nettoyage—mais rajouter des cas devient facile.</p>\n<h2 id=\"bonus--une-démo-rigolote\"><a href=\"#bonus--une-d%C3%A9mo-rigolote\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Bonus : une démo rigolote</h2>\n<p>Ce Hook <code class=\"language-text\">useInterval()</code> est vraiment marrant à utiliser.  Quand les effets de bord sont déclaratifs, il est beaucoup plus facile d’orchestrer plusieurs comportements complexes.</p>\n<p><strong>Par exemple, on peut faire que le <code class=\"language-text\">delay</code> d’un intervalle soit contrôlé par un autre :</strong></p>\n<p><img src=\"/10cfc4b38497a46980d3a13048a56e36/counter_inception.gif\" alt=\"Compteur qui accélère automatiquement\"></p>\n<div class=\"gatsby-highlight has-highlighted-lines\" data-language=\"jsx\"><pre class=\"language-jsx\"><code class=\"language-jsx\"><span class=\"token keyword\">function</span> <span class=\"token function\">Counter</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">const</span> <span class=\"token punctuation\">[</span>delay<span class=\"token punctuation\">,</span> setDelay<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token function\">useState</span><span class=\"token punctuation\">(</span><span class=\"token number\">1000</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token keyword\">const</span> <span class=\"token punctuation\">[</span>count<span class=\"token punctuation\">,</span> setCount<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token function\">useState</span><span class=\"token punctuation\">(</span><span class=\"token number\">0</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n  <span class=\"token comment\">// Incrémenter le compteur.</span>\n  <span class=\"token function\">useInterval</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    <span class=\"token function\">setCount</span><span class=\"token punctuation\">(</span>count <span class=\"token operator\">+</span> <span class=\"token number\">1</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span> delay<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n<span class=\"gatsby-highlight-code-line\">  <span class=\"token comment\">// Accélérer à chaque seconde !</span></span><span class=\"gatsby-highlight-code-line\">  <span class=\"token function\">useInterval</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span></span><span class=\"gatsby-highlight-code-line\">    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>delay <span class=\"token operator\">></span> <span class=\"token number\">10</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span></span><span class=\"gatsby-highlight-code-line\">      <span class=\"token function\">setDelay</span><span class=\"token punctuation\">(</span>delay <span class=\"token operator\">/</span> <span class=\"token number\">2</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></span><span class=\"gatsby-highlight-code-line\">    <span class=\"token punctuation\">}</span></span><span class=\"gatsby-highlight-code-line\">  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span> <span class=\"token number\">1000</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></span>\n  <span class=\"token keyword\">function</span> <span class=\"token function\">handleReset</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token function\">setDelay</span><span class=\"token punctuation\">(</span><span class=\"token number\">1000</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span>\n\n  <span class=\"token keyword\">return</span> <span class=\"token punctuation\">(</span>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span></span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\"></span>\n<span class=\"token plain-text\">      </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>h1</span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\">Compteur : </span><span class=\"token punctuation\">{</span>count<span class=\"token punctuation\">}</span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>h1</span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\"></span>\n<span class=\"token plain-text\">      </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>h4</span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\">Durée : </span><span class=\"token punctuation\">{</span>delay<span class=\"token punctuation\">}</span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>h4</span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\"></span>\n<span class=\"token plain-text\">      </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>button</span> <span class=\"token attr-name\">onClick</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span>handleReset<span class=\"token punctuation\">}</span></span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\"></span>\n<span class=\"token plain-text\">        Réinitialiser la durée</span>\n<span class=\"token plain-text\">      </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>button</span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\"></span>\n<span class=\"token plain-text\">    </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span></span><span class=\"token punctuation\">></span></span>\n  <span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p><em>(Voir la <a href=\"https://codesandbox.io/s/znr418qp13\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">démo sur CodeSandbox</a> !)</em></p>\n<h2 id=\"en-conclusion\"><a href=\"#en-conclusion\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>En conclusion</h2>\n<p>Les Hooks nécessitent de la pratique—<em>en particulier</em> à la frontière entre des codes impératif et déclaratif.  Vous pouvez créer de puissantes abstractions déclaratives grâces à eux, comme <a href=\"http://react-spring.surge.sh/hooks\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">React Spring</a>, mais ils peuvent clairement parfois vous porter sur les nerfs.</p>\n<p>Nous n’en sommes qu’au début des Hooks, et nous avons clairement encore du boulot pour affiner et comparer les solutions et les bonnes pratiques.  Ne précipitez pas votre adoption des Hooks si vous avez plutôt l’habitude de suivre des bonnes pratiques bien établies.  Il nous reste beaucoup de choses à essayer et à découvrir.</p>\n<p>J’espère que cet article vous aura aidés à comprendre les pièges classiques associés à l’utilisation d’APIs telles que <code class=\"language-text\">setInterval()</code> avec les Hooks, à discerner les approches qui peuvent vous aider à vous en dépêtrer, et à goûter le fruit délicieux de la création d’APIs déclaratives plus expressives grâce à eux.</p>","timeToRead":18,"frontmatter":{"title":"Rendre setInterval déclaratif avec les Hooks React","date":"February 04, 2019","spoiler":"Comment j’ai appris à ne plus m’inquiéter et adorer les refs.","tags":null},"fields":{"slug":"/fr/making-setinterval-declarative-with-react-hooks/","langKey":"fr"}}},"pageContext":{"slug":"/fr/making-setinterval-declarative-with-react-hooks/","translations":["fr","zh-hans"],"translatedLinks":[]}}}