React Image onLoad
In React, you can track the state of whether and image has loaded or not by passing the onLoad
prop to an <img />
element.
For my personal website isak.me, I have written the following Header.tsx
component:
<span><span style="color: var(--shiki-token-keyword)">const</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">Header</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> () </span><span style="color: var(--shiki-token-keyword)">=></span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">const</span><span style="color: var(--shiki-color-text)"> [</span><span style="color: var(--shiki-token-constant)">loaded</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">setLoaded</span><span style="color: var(--shiki-color-text)">] </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">useState</span><span style="color: var(--shiki-color-text)">(</span><span style="color: var(--shiki-token-constant)">false</span><span style="color: var(--shiki-color-text)">);</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">const</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">handleOnLoad</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> () </span><span style="color: var(--shiki-token-keyword)">=></span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">setLoaded</span><span style="color: var(--shiki-color-text)">(</span><span style="color: var(--shiki-token-constant)">true</span><span style="color: var(--shiki-color-text)">);</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">return</span><span style="color: var(--shiki-color-text)"> (</span></span>
<span><span style="color: var(--shiki-color-text)"> <</span><span style="color: var(--shiki-token-string-expression)">header</span><span style="color: var(--shiki-color-text)">></span></span>
<span><span style="color: var(--shiki-color-text)"> {</span><span style="color: var(--shiki-token-keyword)">!</span><span style="color: var(--shiki-color-text)">loaded </span><span style="color: var(--shiki-token-keyword)">&&</span><span style="color: var(--shiki-color-text)"> <</span><span style="color: var(--shiki-token-constant)">EmptyContributionGraph</span><span style="color: var(--shiki-color-text)"> />}</span></span>
<span><span style="color: var(--shiki-color-text)"> <</span><span style="color: var(--shiki-token-string-expression)">img</span></span>
<span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">src</span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-token-string-expression)">"https://ghchart.rshah.org/isaksolheim"</span></span>
<span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">className</span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-token-string-expression)">"contribution-graph"</span></span>
<span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">alt</span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-token-string-expression)">"Github contribution graph"</span></span>
<span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">onLoad</span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)">{handleOnLoad}</span></span>
<span><span style="color: var(--shiki-color-text)"> /></span></span>
<span><span style="color: var(--shiki-color-text)"> <</span><span style="color: var(--shiki-token-constant)">TextLink</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">url</span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-token-string-expression)">"/"</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">text</span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-token-string-expression)">"isak.me"</span><span style="color: var(--shiki-color-text)"> /></span></span>
<span><span style="color: var(--shiki-color-text)"> </</span><span style="color: var(--shiki-token-string-expression)">header</span><span style="color: var(--shiki-color-text)">></span></span>
<span><span style="color: var(--shiki-color-text)"> );</span></span>
<span><span style="color: var(--shiki-color-text)">};</span></span>
<span></span>
I use the useState
hook to add React state and keep track of the loaded
value. Once the <img />
has loaded, the function handleOnLoad
runs, which flips the loaded
state from false
to true
. The temporary image <EmptyContributionGraph />
will not disappear.
This is what the final component looks like: