<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/">
    <title>Dan&#x27;s Blog</title>
    <link href="https://blog.danielclubb.com/feed.xml" rel="self" />
    <link href="https://blog.danielclubb.com" />
    <updated>2026-06-05T16:48:28+04:00</updated>
    <author>
        <name>Daniel Clubb</name>
    </author>
    <id>https://blog.danielclubb.com</id>

    <entry>
        <title>UseReducer is Hard Work.</title>
        <author>
            <name>Daniel Clubb</name>
        </author>
        <link href="https://blog.danielclubb.com/usereducer-is-hard-work.html"/>
        <id>https://blog.danielclubb.com/usereducer-is-hard-work.html</id>
            <category term="React"/>
            <category term="Hooks"/>

        <updated>2026-06-05T16:46:40+04:00</updated>
            <summary type="html">
                <![CDATA[
                    The basics const [state, dispatch]&hellip;
                ]]>
            </summary>
        <content type="html">
            <![CDATA[
                <div class="post__toc">
<h3>Table of Contents</h3>
<ul>
<li><a href="#basics">The basics</a>
<ul>
<li><a href="#mcetoc_1jqbt069jg9">First, what the f**k is a reducer?</a></li>
<li><a href="#mcetoc_1jqbt069jga">Why would I use this instead of useState?</a></li>
</ul>
</li>
<li><a href="#parameters">UseReducer's parameters</a>
<ul>
<li><a href="#mcetoc_1jqbt069jgb">What does it return?</a></li>
</ul>
</li>
<li><a href="#remember">Things to remember</a></li>
<li><a href="#example">A real-world example</a></li>
</ul>
</div>
<h2 id="basics" class="site-heading-2">The basics</h2>
<div class="site-body">
<pre class="site-code-block">const [state, dispatch] = useReducer(reducer, initialArg, init?)</pre>
</div>
<h3 id="mcetoc_1jqbt069jg9" class="site-heading-3">First, what the f**k is a reducer?</h3>
<blockquote class="w-full border-l-4 border-violet-500 pl-4 text-left text-lg italic leading-8 text-zinc-600 dark:border-violet-400 dark:text-zinc-400">A function that takes state and action as arguments and returns the next state of the app.</blockquote>
<p class="site-body">That definition isn't super helpful.</p>
<p class="site-body">A reducer in React is just a function that takes the <strong>current state</strong> and an action, then returns a <strong>new state</strong>. Here's an example:</p>
<pre class="site-code-block">function reducer(state, action) {
    switch (action.type) {
        case "increment":
            return { count: state.count + 1 };

        case "decrement":
            return { count: state.count - 1 };

        default:
            return state;
    }
}</pre>
<p class="site-body">If React sends this action:</p>
<pre class="site-code-block">{ type: "increment" }</pre>
<p class="site-body">The reducer function thinks</p>
<blockquote class="w-full border-l-4 border-violet-500 pl-4 text-left text-lg italic leading-8 text-zinc-600 dark:border-violet-400 dark:text-zinc-400">Okay, I'll increase the count by 1</blockquote>
<h3 id="mcetoc_1jqbt069jga" class="site-heading-3">Why would I use this instead of <code class="site-code-inline">useState</code>?</h3>
<p>A good rule of thumb is <strong>simple state = <code class="site-code-inline">useState</code></strong>, <strong>complex state = <code class="site-code-inline">useReducer</code>.</strong></p>
<p class="site-body">With useReducer, instead of directly changing state like this:</p>
<pre class="site-code-block">setCount(count + 1);</pre>
<p class="site-body">You dispatch "actions" to the reducer, and it decides what the new state should be, e.g.:</p>
<pre class="site-code-block">dispatch({ type: "increment" });</pre>
<h2 id="parameters" class="site-heading-2">UseReducer's parameters</h2>
<div class="site-body">
<pre class="site-code-block">const [state, dispatch] = useReducer(reducer, initialArg, init?)</pre>
</div>
<ul class="w-full list-inside list-disc space-y-4 text-left text-lg leading-8 text-zinc-600 dark:text-zinc-400 marker:text-zinc-400 dark:marker:text-zinc-500">
<li><code class="site-code-inline">reducer</code>: The reducer function that specifies how the state gets updated. It must be pure, should take the state and action as arguments, and should return the next state. State and action can be of any types.</li>
<li><code class="site-code-inline">initialArg</code>: The value from which the initial state is calculated. It can be a value of any type. How the initial state is calculated from it depends on the next init argument.</li>
<li>(Optional) <code class="site-code-inline">init</code>: The initializer function that should return the initial state. If it's not specified, the initial state is set to initialArg. Otherwise, the initial state is set to the result of calling init(initialArg).</li>
</ul>
<h3 id="mcetoc_1jqbt069jgb" class="site-heading-3">What does it return?</h3>
<p class="site-body"><code class="site-code-inline">useReducer</code> returns an array of two values:</p>
<ol class="w-full list-inside list-decimal space-y-4 text-left text-lg leading-8 text-zinc-600 dark:text-zinc-400 marker:text-zinc-400 dark:marker:text-zinc-500">
<li>The current state</li>
<li>The dispatch function that lets you update the state to a different value and trigger a re-render.</li>
</ol>
<h2 id="remember" class="site-heading-2">Things to remember</h2>
<p class="site-body">A reducer must be a pure function. <i>What is a pure function?</i>, a pure function is a function that relies solely on its input parameters, and does not take into account any outside variables or state in returning a value.</p>
<p class="site-body">A pure function must also <strong>not mutate its arguments.</strong></p>
<p class="site-body">This is pure:</p>
<pre class="site-code-block">function addNumbers(numberOne, numberTwo) {
    return numberOne + numberTwo;
}</pre>
<p class="site-body">This is impure:</p>
<pre class="site-code-block">const numberToAdd = 3;

function addNumbers(numberOne) {
    return numberOne + numberToAdd;
}</pre>
<p class="site-body">It is also worth remembering that a pure function must never mutate its arguments, e.g.:</p>
<pre class="site-code-block">const [questions, setQuestions] = useState([]);

function addQuestion(currentState, newQuestion) {
    currentState.push(newQuestion);
    return currentState;
}

addQuestion(questions, 'new question to add');</pre>
<p class="site-body">This is <strong>impure</strong> because it is directly mutating the <code class="site-code-inline">questions</code> state, by pushing to it.</p>
<p class="site-body">Instead, do this:</p>
<pre class="site-code-block">const [questions, setQuestions] = useState([]);

function addQuestion(currentState, newQuestion) {
    return [...currentState, newQuestion];
}

addQuestion(questions, 'new question to add');</pre>
<h2 id="example" class="site-heading-2">A real-world example</h2>
<p class="site-body">Forms are a great place to make use of <code class="site-code-inline">useReducer</code>, as they often have complex state objects that need to be managed efficiently.</p>
<pre class="site-code-block">const initialFormState: FormStateType = {
    name: '',
    email: ''
}

interface FormStateType {
    name: string;
    email: string;
}
interface ActionType {
    type: string;
    field: string;
    value: string;
}

function formDataReducer(state: FormStateType, action: ActionType) {
    switch (action.type) {
        case 'FIELD_CHANGED':
            return {
                ...state,
                [action.field]: action.value
            }
        case 'FORM_CLEARED':
            return {
                ...initialFormState
            }
        default:
            return {
                ...state
            }
    }
}

const [formData, dispatchFormData] = useReducer(formDataReducer, initialFormState);</pre>
<p class="site-body">This is a textbook example. Here, we're able to update form fields and clear the form (and add any other logic we want), in a single reducer function.</p>
<p class="site-body">Here's an example of what the form component's code would look like:</p>
<pre class="site-code-block">&lt;form action=""&gt;
    &lt;input 
        type="text" 
        name="name" 
        id="name"
        value={formData.name}
        onChange={e =&gt;
            dispatchFormData({
                type: 'FIELD_CHANGED',
                field: 'name',
                value: e.target.value,
            })
        }
    /&gt;
    &lt;input 
        type="email" 
        name="email" 
        id="email"
        value={formData.email}
        onChange={e =&gt;
            dispatchFormData({
                type: 'FIELD_CHANGED',
                field: 'email',
                value: e.target.value,
            })
        }
    /&gt;
&lt;/form&gt;</pre>
            ]]>
        </content>
    </entry>
    <entry>
        <title>The UseCallback Hook.</title>
        <author>
            <name>Daniel Clubb</name>
        </author>
        <link href="https://blog.danielclubb.com/the-usecallback-hook.html"/>
        <id>https://blog.danielclubb.com/the-usecallback-hook.html</id>
            <category term="React"/>
            <category term="Hooks"/>

        <updated>2026-06-05T16:41:49+04:00</updated>
            <summary type="html">
                <![CDATA[
                    The Basics useCallback(fn, dependencies) Right.
                ]]>
            </summary>
        <content type="html">
            <![CDATA[
                <article class="site-article"><nav class="site-nav-toc" aria-label="On this page">
<div class="post__toc">
<h3>Table of Contents</h3>
<ul>
<li><a href="#mcetoc_1jqbspcsmfu">The Basics</a>
<ul>
<li><a href="#mcetoc_1jqbsolv8fp">What's the difference between useCallback and useMemo?</a></li>
</ul>
</li>
<li><a href="#mcetoc_1jqbsolv8fq">With Typescript</a></li>
</ul>
</div>
</nav>
<h2 id="mcetoc_1jqbspcsmfu" aria-label="On this page">The Basics</h2>
<div class="site-body w-full">
<pre class="site-code-block">useCallback(fn, dependencies)</pre>
</div>
<p class="site-body">Right. Let's do this.</p>
<p class="site-body">React does too much. Every time your component re-renders, <strong>everything</strong> inside of it (including your functions) are re-created.</p>
<p class="site-body">Even if your function hasn't changed, React sees a "new" version on every render.</p>
<p class="site-body">Usually, this isn't an issue, but it becomes an issue when you're passing the function down to a child that's trying to maintain efficiency.</p>
<p class="site-body"><strong>The problem: </strong>Without <code class="site-code-inline">useCallback</code>, a child component might re-render unnecessarily because it thinks it received a "brand new" function from the parent, even if nothing actually changed.</p>
<p class="site-body"><strong>The solution: </strong><code class="site-code-inline">useCallback</code> Ensures the function maintains the same "identity" across renders.</p>
<h3 id="mcetoc_1jqbsolv8fp" class="site-heading-3">What's the difference between useCallback and useMemo?</h3>
<p class="site-body"><strong><code class="site-code-inline">useMemo</code></strong> Memoises (remembers) the <strong>result or the value returned</strong> by a function.</p>
<pre class="site-code-block">function AdditionComponent(firstNumber, secondNumber) {
    const additionResult = useMemo(() =&gt; {
        return firstNumber + secondNumber;
    }, [firstNumber, secondNumber]);
}
                        </pre>
<p class="site-body">In this case, <code class="site-code-inline">useMemo</code> will cache the <strong>value</strong> returned by the <code class="site-code-inline">additionResult</code> function. So if <code class="site-code-inline">firstNumber = 1</code> and <code class="site-code-inline">secondNumber = 2</code>, the cached result will be <code class="site-code-inline">3</code>.</p>
<p class="site-body"><strong><code class="site-code-inline">useCallback</code></strong> remembers (caches) the <strong>function itself.</strong></p>
<pre class="site-code-block">function AdditionComponent(firstNumber, secondNumber) {
    const handleAddition = useCallback(() =&gt; {
        return firstNumber + secondNumber;
    }, [firstNumber, secondNumber]);
}
                        </pre>
<p class="site-body">In this case, <code class="site-code-inline">useCallback</code> caches the <strong>function itself</strong>, and will only re-create the function if either of its dependencies (<code class="site-code-inline">firstNumber</code> or <code class="site-code-inline">secondNumber</code>) change.</p>
<pre class="site-code-block">function AdditionComponent(firstNumber, secondNumber) {
    const additionResult = useMemo(() =&gt; {
        return firstNumber + secondNumber
    }, [firstNumber, secondNumber]);
}
                        </pre>
<p class="site-body"><strong>Note: </strong><code class="site-code-inline">useCallback</code> is essentially just a specific implementation of <code class="site-code-inline">useMemo</code>, designed <u>only</u> to store functions. Caching a value? Use <code class="site-code-inline">useMemo</code>. Caching a function? Use <code class="site-code-inline">useCallback</code></p>
</article>
<article id="typescript" class="site-article mt-16 border-t border-zinc-200 pt-16 dark:border-zinc-800">
<h2 id="mcetoc_1jqbsolv8fq" class="site-heading-2">With Typescript</h2>
<p class="site-body">Great news! You don't <i><strong>need</strong></i> to explicitly type this.</p>
<p class="site-body"><code class="site-code-inline">useCallback</code> also uses <strong>type inference (noticing a pattern, yet?)</strong>.</p>
</article>
            ]]>
        </content>
    </entry>
    <entry>
        <title>The UseRef Hook.</title>
        <author>
            <name>Daniel Clubb</name>
        </author>
        <link href="https://blog.danielclubb.com/the-useref-hook.html"/>
        <id>https://blog.danielclubb.com/the-useref-hook.html</id>
            <category term="React"/>
            <category term="Hooks"/>

        <updated>2026-06-05T16:17:58+04:00</updated>
            <summary type="html">
                <![CDATA[
                    The basics useRef(initialValue) Hopefully this&hellip;
                ]]>
            </summary>
        <content type="html">
            <![CDATA[
                <article class="site-article"><nav class="site-nav-toc" aria-label="On this page"></nav>
<div class="post__toc">
<h3>Table of Contents</h3>
<ul>
<li><a href="#basics">The basics</a>
<ul>
<li><a href="#mcetoc_1jqbrf79sfc">Things worth knowing</a></li>
</ul>
</li>
<li><a href="#basics">A real-world example</a></li>
</ul>
</div>
<h2 id="basics" class="site-heading-2">The basics</h2>
<div class="site-body w-full">
<pre class="site-code-block">useRef(initialValue)</pre>
</div>
<p class="site-body">Hopefully this should be a quick one.</p>
<p class="site-body"><code class="site-code-inline">useRef</code> is used for storing a value across renders, without causing a re-render when it is changed.</p>
<p class="site-body"><code class="site-code-inline">useState</code> causes the component to re-render when it is changed.</p>
<p class="site-body"><code class="site-code-inline">useRef</code> <strong><u>doesn't</u></strong> cause the component to re-render. Simple, really.</p>
<h3 id="mcetoc_1jqbrf79sfc" class="site-heading-3">Things worth knowing</h3>
<ul class="site-link-list max-w-2xl text-left">
<li><code class="site-code-inline">useRef</code> is mutable. Which means it can be changed.</li>
<li><code class="site-code-inline">useRef</code> returns an object with property <code class="site-code-inline">current</code>.</li>
<li>To update the <code class="site-code-inline">useRef</code>'s value, update the <code class="site-code-inline">current</code> property, like below:</li>
</ul>
<pre class="site-code-block">const numberRef = useRef(0);

numberRef.current = 5;
numberRef.current += 1;

// numberRef is now equal to 6</pre>
</article>
<article id="typescript" class="site-article mt-16 border-t border-zinc-200 pt-16 dark:border-zinc-800">
<h2 id="basics" class="site-heading-2">A real-world example</h2>
<p>Let's say you want to create a React hook called <code>useTimeout</code> which invokes a callback after a specified delay. The hook should <strong>always</strong> invoke the latest callback it is given, without restarting the running timeout.</p>
<pre>function useTimeout(delay, callback) {<br>    const latestCallback = callback;<br>    latestCallback.current = callback;<br><br>    useEffect(() =&gt; {<br>        const timeoutId = setTimeout(() =&gt; {<br>            latestCallback.current();<br>        }, delay);<br><br>        return () =&gt; clearTimeout(timeoutId);<br>    }, [delay]);<br>}</pre>
<p>Here, we're persisting <code>latestCallback</code> across renders, and reassigning its <code>current</code> property if a new callback function is received, without causing the existing timeout to be restarted.</p>
<p>Most commonly however, you'll see <code>useRef</code> attached to components/elements using the special <code>ref</code> attribute, e.g.:</p>
<pre>const inputElementRef = useRef(null);<br><br>...<br><br>&lt;input type="text" ref={inputElementRef} /&gt;</pre>
<p>This enables us to access and perform operations on the underlying component by accessing <code>inputElementRef.current</code>, e.g.:</p>
<pre>inputElementRef.current.focus();</pre>
</article>
            ]]>
        </content>
    </entry>
    <entry>
        <title>The UseMemo Hook.</title>
        <author>
            <name>Daniel Clubb</name>
        </author>
        <link href="https://blog.danielclubb.com/the-usememo-hook.html"/>
        <id>https://blog.danielclubb.com/the-usememo-hook.html</id>
            <category term="React"/>
            <category term="Hooks"/>

        <updated>2026-06-05T14:02:03+04:00</updated>
            <summary type="html">
                <![CDATA[
                    The Basics useMemo is your way&hellip;
                ]]>
            </summary>
        <content type="html">
            <![CDATA[
                <article class="site-article"><nav class="site-nav-toc" aria-label="On this page">
<div class="post__toc">
<h3>Table of Contents</h3>
<ul>
<li><a href="#mcetoc_1jqbjk49i2db">The Basics</a>
<ul>
<li><a href="#mcetoc_1jqbjfp282d2">The calculateValue argument</a></li>
<li><a href="#mcetoc_1jqbjfp282d3">The dependency array argument</a>
<ul>
<li><a href="#mcetoc_1jqbjfp282d4">But what if I don't pass a dependency array?</a></li>
<li><a href="#mcetoc_1jqbjfp282d5">But what if I pass an empty dependency array?</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#mcetoc_1jqbjfp282d6">With Typescript</a></li>
</ul>
</div>
</nav>
<h2 id="mcetoc_1jqbjk49i2db">The Basics</h2>
<p><code class="site-code-inline">useMemo</code> is your way of telling React to be lazy.</p>
<div> </div>
<div class="site-body">Here's how it should be called:
<pre class="site-code-block">useMemo(calculateValue, dependencies)</pre>
But what does that mean?</div>
<p class="site-body"><code class="site-code-inline">useMemo</code> acts as a store of a value. It stores the result of a function so that React doesn't have to re-calculate it every time the component re-renders.</p>
<p class="site-body">Here's an example. Say we have component that has to render a list of 100,000 items:</p>
<pre class="site-code-block">function SearchList({ items, query }) {
    // This runs on EVERY single render, even if 'items' hasn't changed!
    const filteredItems = items.filter(item =&gt; item.includes(query));

    return &lt;ul&gt;{filteredItems.map(i =&gt; &lt;li key={i}&gt;{i}&lt;/li&gt;)}&lt;/ul&gt;;
}</pre>
<p class="site-body">Even if <code class="site-code-inline">items</code> doesn't change, the <code class="site-code-inline">filter</code> function will be called every time the component re-renders.</p>
<p class="site-body">This is, obviously, shit.</p>
<p class="site-body">The solution in this case is to use <code class="site-code-inline">useMemo</code>, to store the filtered <code class="site-code-inline">items</code> array between re-renders.</p>
<pre class="site-code-block">const filteredItems = useMemo(() =&gt; {
    return items.filter(item =&gt; item.includes(query));
}, [items, query]); // Only re-run if 'items' or 'query' change</pre>
<h3 id="mcetoc_1jqbjfp282d2" class="site-heading-3">The <code class="site-code-inline">calculateValue</code> argument</h3>
<div> </div>
<div class="site-body">Hmmm, I wonder what <code class="site-code-inline">calculateValue</code> is?</div>
<div> </div>
<div class="site-body">Well, it's a function that <strong>calulates value</strong>, obviously.
<pre class="site-code-block">const addedNumbers = useMemo(() =&gt; {
    return numberA + numberB;
},[numberA, numberB])</pre>
In this scenario, if either <code class="site-code-inline">numberA</code> or <code class="site-code-inline">numberB</code> change, the function that adds them together will be re-called.</div>
<p class="site-body">Simple, right?</p>
<h3 id="mcetoc_1jqbjfp282d3" class="site-heading-3">The <code class="site-code-inline">dependency</code> array argument</h3>
<p class="site-body">This is just the same as the <code class="site-code-inline">useEffect</code> dependency array. If any of the values in the array change, the <code class="site-code-inline">calculateValue</code> function will be called.</p>
<h4 id="mcetoc_1jqbjfp282d4" class="site-heading-4">What if I don't pass a dependency array?</h4>
<p class="site-body"><strong>If you don't pass a dependency array to <code class="site-code-inline">useMemo</code>, <u>it essentially becomes useless.</u></strong><br>No dependency array? Then the <code class="site-code-inline">calculateValue</code> function is called every render. And that's very silly isn't it, because that's what we're trying to avoid here.</p>
<h4 id="mcetoc_1jqbjfp282d5" class="site-heading-4">What if I pass an empty dependency array?</h4>
<p class="site-body">Another good question,<br>If you pass an empty dependency array to <code class="site-code-inline">useEffect</code>, you're telling React:<br><strong>"Run this code exactly once, and then never touch it again."</strong></p>
</article>
<article id="typescript" class="site-article mt-16 border-t border-zinc-200 pt-16 dark:border-zinc-800">
<h2 id="mcetoc_1jqbjfp282d6" class="site-heading-2">With Typescript</h2>
<p class="site-body">Great news! You don't <i><strong>need</strong></i> to explicitly type this.</p>
<p class="site-body"><code class="site-code-inline">useMemo</code> also uses <strong>type inference (noticing a pattern, yet?)</strong>.</p>
<div class="site-body">Here's an example:
<pre class="site-code-block">const addedNumbers = useMemo(() =&gt; {
    return numberA + numberB;
},[numberA, numberB])</pre>
This <code class="site-code-inline">calculateValue</code> function returns a number, so Typescript will <strong>infer</strong> that it should <u><strong>always</strong></u> return a number.</div>
<div> </div>
<div class="site-body">If you want to be able to return complex types (i.e. an object), here's what you should do:
<pre class="site-code-block">interface UserData {
    id: number;
    name: string;
}

const formattedData = useMemo&lt;UserData&gt;(() =&gt; {
    return {
        id: 69,
        name: "Dan"
    }
},[numberA, numberB])
                            </pre>
</div>
</article>
            ]]>
        </content>
    </entry>
    <entry>
        <title>UseEffect, What Does It Do?</title>
        <author>
            <name>Daniel Clubb</name>
        </author>
        <link href="https://blog.danielclubb.com/useeffect-what-does-it-do.html"/>
        <id>https://blog.danielclubb.com/useeffect-what-does-it-do.html</id>
            <category term="React"/>
            <category term="Hooks"/>

        <updated>2026-06-05T13:48:10+04:00</updated>
            <summary type="html">
                <![CDATA[
                    The basics I'll start by&hellip;
                ]]>
            </summary>
        <content type="html">
            <![CDATA[
                <article class="site-article">
<div class="post__toc">
<h3>Table of Contents</h3>
<ul>
<li><a href="#basics">The basics</a>
<ul>
<li><a href="#mcetoc_1jqbifl1f29p">The setup argument</a>
<ul>
<li><a href="#mcetoc_1jqbifl1f29q">What if I don't pass a dependency array?</a></li>
<li><a href="#mcetoc_1jqbifl1f29r">What if I pass an empty dependency array?</a></li>
</ul>
</li>
<li><a href="#mcetoc_1jqbifl1f29s">WTF is a cleanup function?</a></li>
</ul>
</li>
<li><a href="#mcetoc_1jqbifl1f29t">With Typescript</a></li>
</ul>
</div>
<h2 id="basics" class="site-heading-2">The basics</h2>
<p class="site-body">I'll start by saying I think <code>useEffect</code> is a stupid name.</p>
<p class="site-body">Long story short, <code class="site-code-inline">useEffect</code> is a way to tell React <i><strong>"After you've finished updating the DOM, run this extra bit of code."</strong></i></p>
<p>Here's how it should be called:</p>
<div class="site-body">
<pre class="site-code-block">useEffect(setup, dependencies?)</pre>
But what does that even mean?</div>
<h3 id="mcetoc_1jqbifl1f29p" class="site-heading-3">The <code class="site-code-inline">setup</code> argument</h3>
<p> </p>
<div class="site-body"><code class="site-code-inline">setup</code> is the logic function of the "effect".</div>
<div class="site-body"><br>When the component mounts, or the dependency array changes (we'll get to that next), React runs the setup function. Here's an example:
<pre class="site-code-block">const [count, setCount] = useState(0);

useEffect(() =&gt; {
    document.title = `You clicked ${count} times`;
}, [count]);</pre>
The <code class="site-code-inline">dependency</code> array argument</div>
</article>
<article class="site-article">
<p class="site-body">In the example above, we called <code class="site-code-inline">useEffect</code> with <code class="site-code-inline">[count]</code> as the dependencies argument. This means that our <code class="site-code-inline">useEffect</code> function is "listening" for the <code class="site-code-inline">count</code> state variable to change. It will call the <code class="site-code-inline">setup</code> function whenever <code class="site-code-inline">count</code> changes.</p>
<p><strong>Also</strong>, as a bonus, it will also run whenever the component mounts.</p>
<p class="site-body">Go ahead, try it, I dare you. Reload the page. Notice how the page title is already <strong>Count: 0</strong> before you've even pressed the button?</p>
<h4 id="mcetoc_1jqbifl1f29q" class="site-heading-4">What if I don't pass a dependency array?</h4>
<p class="site-body">Good question. And here's a good answer.</p>
<p class="site-body"><strong>If you don't pass a dependency array to <code class="site-code-inline">useEffect</code>, the <code class="site-code-inline">setup</code> function will be called on every single re-render.</strong><br>...so (except in rare circumstances), it's probably best to pass a dependency array. Or not. I don't care really.</p>
<h4 id="mcetoc_1jqbifl1f29r" class="site-heading-4">What if I pass an empty dependency array?</h4>
<p class="site-body">Another good question.</p>
<p>If you pass an empty dependency array to <code class="site-code-inline">useEffect</code>, you're telling React:<br><strong>"Run this code exactly once, and then never touch it again.".</strong></p>
<p>This is useful for things like API calls, when you only want to fetch data from the server once when the page loads.</p>
<h3 id="mcetoc_1jqbifl1f29s" class="site-heading-3">WTF is a cleanup function?</h3>
<p class="site-body">This is actually quite easy to explain. If you return a function from the <code class="site-code-inline">setup</code> function, <strong>congratulations</strong>, that's a cleanup function.</p>
<pre class="site-code-block">useEffect(() =&gt; {
    document.title = `Count: ${count}`;

    // Here's your cleanup function
    return () =&gt; {
        document.title = "Count cleared";
    }
}, [count]);</pre>
<p class="site-body">When is the <code class="site-code-inline">cleanup</code> function called? Whenever the component unmounts.</p>
<p class="site-body">Think of it as turning the TV off and locking the doors before you go out. The <code class="site-code-inline">cleanup</code> function is used to tidy up your mess before the component unmounts. It's useful for things like:</p>
<ul>
<li><span style="font-size: inherit;">Ending intervals/timers</span></li>
<li>Disconnecting from websockets</li>
<li>Etc. (I ran out of ideas)</li>
</ul>
<p>A common use-case is for tearing-down things like event listeners:</p>
<pre>useEffect(() =&gt; {<br>    const handler = () =&gt; {<br>        ...<br>    };<br><br>    window.addEventListener("click", handler);<br>    return () =&gt; window.removeEventListener("click", handler);<br>}, []);</pre>
</article>
<article id="typescript" class="site-article mt-16 border-t border-zinc-200 pt-16 dark:border-zinc-800">
<p>That way, we clean up event listeners each time the dependencies change.</p>
<h2 id="mcetoc_1jqbifl1f29t" class="site-heading-2">With Typescript</h2>
<p class="site-body">Great news! You don't <i><strong>need</strong></i> to explicitly type this, <code class="site-code-inline">useEffect</code> also uses <strong>type inference</strong>.</p>
<p>Here's an example:</p>
<div class="site-body">
<pre class="site-code-block">useEffect(() =&gt; {
    document.title = `Count: ${count}`;
}, [count]);</pre>
In this case, typescript will <i><strong>infer</strong></i> that the <code class="site-code-inline">dependency array</code> will be an array which matches the type of <code class="site-code-inline">count</code>, which is a number.</div>
<p class="site-body">The <code class="site-code-inline">setup</code> function, should be exactly that... a function. Not an async function. Just a regular old function.</p>
<p class="site-body">If you need to do async stuff inside the <code class="site-code-inline">useEffect</code> setup function, it should be <strong>wrapped</strong> inside a regular, synchronous function, like this:</p>
<pre class="site-code-block">useEffect(() =&gt; {
    const performAsyncTask = async () =&gt; {
        // async logic here
    };
    performAsyncTask();
}, []);</pre>
<p class="site-body"><strong>Not</strong> like this:</p>
<pre class="site-code-block">useEffect(async () =&gt; {
    const data = await fetchData();
}, []);</pre>
<p class="site-body">Because you'll get the following error:</p>
<pre class="site-code-block">    Argument of type '() =&gt; Promise&lt;void&gt;' is not assignable to parameter of type 'EffectCallback'.
    Type 'Promise&lt;void&gt;' is not assignable to type 'void | Destructor'.</pre>
</article>
            ]]>
        </content>
    </entry>
    <entry>
        <title>UseState is Easy.</title>
        <author>
            <name>Daniel Clubb</name>
        </author>
        <link href="https://blog.danielclubb.com/usestate-is-easy.html"/>
        <id>https://blog.danielclubb.com/usestate-is-easy.html</id>
            <category term="React"/>
            <category term="Hooks"/>

        <updated>2026-06-05T13:34:00+04:00</updated>
            <summary type="html">
                <![CDATA[
                    The basics With Typescript The&hellip;
                ]]>
            </summary>
        <content type="html">
            <![CDATA[
                <article class="site-article"><nav class="site-nav-toc" aria-label="On this page">
<ul>
<li><a href="http://localhost:3000/react/hooks/useState#basics">The basics</a></li>
<li><a href="http://localhost:3000/react/hooks/useState#typescript">With Typescript</a></li>
</ul>
</nav>
<h2 id="basics" class="site-heading-2">The basics</h2>
<p class="site-body">It's simple. React's <code class="site-code-inline">useState</code> hook stores state.</p>
<div class="site-body">You define it with a state name and a function for updating the state, define a default state (or not, whatever), and then call the updater function whenever you want to update it. Simple.<br>
<pre class="site-code-block">const [count, setCount] = useState(0);</pre>
<br>Here, <code class="site-code-inline">count</code> is the state variable, and <code class="site-code-inline">setCount</code> is the updater or "set" function, which is called to update the state.</div>
<div> </div>
<div>Count can then be changed by calling <code>setCount</code> like this:</div>
<pre>setCount(newValue);</pre>
</article>
<article id="typescript" class="site-article mt-16 border-t border-zinc-200 pt-16 dark:border-zinc-800">
<p>Each time the state is changed, the entire component will be re-rendered.</p>
<h2 class="site-heading-2">With Typescript</h2>
<p class="site-body">Great news! You don't <i><strong>need</strong></i> to explicitly type this.</p>
<p class="site-body">Ready for some real developer jargon? <code class="site-code-inline">useState</code> is designed with <strong>type inference</strong>.</p>
<p class="site-body">What does that mean? No one knows what it means, but it's provocative.</p>
<p>No, actually, we do know what it means. It means that Typescript is clever enough to look at what type you set the state variable to initially, and just use that, forever.</p>
<div class="site-body">Here's an example
<pre class="site-code-block">const [count, setCount] = useState(0);</pre>
In this case, typescript will <i><strong>infer</strong></i> that <code class="site-code-inline">count</code> should be a number, forever.</div>
<div class="site-body">That means that if you fuck around and try to call <code class="site-code-inline">setCount</code> with a <strong>string</strong>, you'll find out, and Typescript will moan at you.
<pre class="site-code-block">onClick={() =&gt; setCount("test") //attempting to set count to string</pre>
</div>
<div class="site-body">Here's the error:
<pre class="site-code-block">Argument of type 'string' is not assignable to parameter of type 'SetStateAction&lt;number&gt;'.</pre>
</div>
<h3 class="site-heading-3">But what if I want to be able to change the state's type?</h3>
<div class="site-body">Simple, when defining the `count` state...</div>
<div class="site-body"><br>Instead of this:
<pre class="site-code-block">const [count, setCount] = useState(0);</pre>
Do this:
<pre class="site-code-block">const [count, setCount] = useState&lt;string | number&gt;(0);</pre>
Now <code class="site-code-inline">count</code> can be either a string or a number.</div>
</article>
            ]]>
        </content>
    </entry>
    <entry>
        <title>Say you. Say me. Say it together. UseId.</title>
        <author>
            <name>Daniel Clubb</name>
        </author>
        <link href="https://blog.danielclubb.com/say-you-say-me-say-it-together-useid.html"/>
        <id>https://blog.danielclubb.com/say-you-say-me-say-it-together-useid.html</id>
            <category term="React"/>
            <category term="Hooks"/>

        <updated>2026-06-04T12:00:32+04:00</updated>
            <summary type="html">
                <![CDATA[
                    The basics useId is pretty much all&hellip;
                ]]>
            </summary>
        <content type="html">
            <![CDATA[
                <div class="post__toc">
<h3>Table of Contents</h3>
<ul>
<li><a href="#basics">The basics</a></li>
<li><a href="#example">Here's a real-world example</a></li>
</ul>
</div>
<h2 id="basics" class="site-heading-2">The basics</h2>
<p class="site-body"><code class="site-code-inline">useId</code> is pretty much <i>all </i>basics. It doesn't take any arguments.</p>
<pre class="site-code-block">const id = useId();</pre>
<p class="site-body">It's just an easy way of generating a random, unique ID for an element.</p>
<p class="site-body">Why? Well, there's a few benefits:</p>
<ul class="mt-4 w-full list-outside list-disc space-y-4 pl-6 text-left text-lg leading-8 text-zinc-600 marker:text-zinc-400 dark:text-zinc-400 dark:marker:text-zinc-500">
<li><code class="site-code-inline">useId</code> avoids collisions by default. Even if a component is rendered multiple times on the same page, <code class="site-code-inline">useId</code> ensures that all of the components have unique ID attributes.</li>
<li>Enables server-side rendering consistency. <code class="site-code-inline">useId</code> creates an ID on the server. Then during client hydration, it will use the same ID, preventing hydration errors.</li>
</ul>
<h2 id="example" class="site-heading-2">Here's a real-world example</h2>
<p class="site-body">Here, we generate IDs for each input, and the form itself, using <code class="site-code-inline">useId</code>.</p>
<p class="site-body">Then we can use the generated IDs for both the inputs and the input labels, to ensure they are always consistent with one another.</p>
<pre class="site-code-block">const FormComponent = () =&gt; {
    const formID = useId();
    const nameInputID = useId();
    const emailInputID = useId();


    return (
        &lt;form action="" id={formID}&gt;
            &lt;label htmlFor={nameInputID}&gt;Name:&lt;/label&gt;
            &lt;input type="text" name="name" id={nameInputID} /&gt;
            &lt;label htmlFor={emailInputID}&gt;Email:&lt;/label&gt;
            &lt;input type="email" name="" id={emailInputID} /&gt;
        &lt;/form&gt;
    )
};
                        </pre>
<p class="site-body">Here's the benefit, if we render that component multiple times, each instance will have its own set of unique IDs, which avoids having invalid HTML due to repeated element IDs:</p>
<pre class="site-code-block">&lt;form action="" id="_S_1_"&gt;
    &lt;label for="_S_2_"&gt;Name:&lt;/label&gt;
    &lt;input id="_S_2_" type="text" name="name"&gt;
    &lt;label for="_S_3_"&gt;Email:&lt;/label&gt;
    &lt;input id="_S_3_" type="email" name=""&gt;
&lt;/form&gt;

&lt;form action="" id="_S_4_"&gt;
    &lt;label for="_S_5_"&gt;Name:&lt;/label&gt;
    &lt;input id="_S_5_" type="text" name="name"&gt;
    &lt;label for="_S_6_"&gt;Email:&lt;/label&gt;
    &lt;input id="_S_6_" type="email" name=""&gt;
&lt;/form&gt;
                        </pre>
<p class="site-body">If we used hard-coded <code class="site-code-inline">id</code>attributes on the component, if we were to re-use the same component multiple times on the page, we'd have repeated element IDs.</p>
            ]]>
        </content>
    </entry>
</feed>
