React Hooks Crash Course
Published: 2023-08-07 04:49:56

<h1 id="heading-react-hooks">React Hooks</h1>
<ul>
<li><code>useEffect</code> is use to handle component side effects. Generally used in fetching data, subscribing to events or updating title. The first argument is an callback function that contains the effect we want to run and callback will be called after the component is rendered.</li>
</ul>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> { useEffect, useState } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">MyComponent</span>(<span class="hljs-params">{ id }</span>) </span>{
  <span class="hljs-keyword">const</span> [data, setData] = useState(<span class="hljs-literal">null</span>);

  useEffect(<span class="hljs-function">() =&gt;</span> {
    fetch(<span class="hljs-string">`https://my-api.com/data/<span class="hljs-subst">${id}</span>`</span>)
      .then(<span class="hljs-function"><span class="hljs-params">response</span> =&gt;</span> response.json())
      .then(<span class="hljs-function"><span class="hljs-params">data</span> =&gt;</span> setData(data));
  }, [id]);

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      {data ? <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Data: {data}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span> : <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Loading...<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>}
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}
</code></pre>
<ul>
<li><code>useState</code> is a hook that allows you to add state to a functional component in React. State is a way to store and manage data that can change over time. It allows you to keep track of data that your component needs to render, such as a value entered in an input field or a toggle state.</li>
</ul>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> { useState } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">MyComponent</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [count, setCount] = useState(<span class="hljs-number">0</span>);

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Count: {count}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{()</span> =&gt;</span> setCount(count + 1)}&gt;Increment<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}
</code></pre>
<p>useState returns an array containing two elements, the first one is the current state, and the second one is a function that allows you to update the state.</p>
<ul>
<li><code>useMemo</code> is used to memoize a value that's expensive to calculate. It takes a function that returns a value and an array of dependencies as arguments. It will only recalculate the value when one or more of the dependencies have changed. The value is then passed as a prop to a child component, and the child component only re-renders when the value changes.</li>
</ul>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> { useMemo } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">MyComponent</span>(<span class="hljs-params">{data}</span>) </span>{
  <span class="hljs-keyword">const</span> memoizedData = useMemo(<span class="hljs-function">() =&gt;</span> expensiveCalculation(data), [data]);

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Data: {memoizedData}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}
</code></pre>
<ul>
<li><code>useCallback</code> is used to memoize a callback function. It takes a callback function and an array of dependencies as arguments. It will return a new callback function only when one or more of the dependencies have changed. The callback function is then passed as a prop to a child component, and the child component only re-renders when the callback function changes.</li>
</ul>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> { useCallback } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">MyParentComponent</span>(<span class="hljs-params">{data}</span>) </span>{
  <span class="hljs-keyword">const</span> handleClick = useCallback(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(data);
  }, [data]);

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">MyChildComponent</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{handleClick}</span> /&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}
</code></pre>
<ul>
<li><p>In summary, <code>useMemo</code> is used to memoize a value and <code>useCallback</code> is used to memoize a function. Both are used to make your component more performant by avoiding unnecessary calculations or re-renders.</p>
</li>
<li><p><code>useReducer</code> is a hook that allows you to manage state in a functional component using the concept of a "reducer" function. It's similar to <code>useState</code>, but it is more powerful and flexible, and is better suited for handling complex state updates. The <code>useReducer</code> hook takes two arguments, the first one is the reducer function, and the second one is the initial state. It returns an array containing the current state and a dispatch function that allows you to update the state by dispatching an action.</p>
</li>
</ul>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> { useReducer } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">reducer</span>(<span class="hljs-params">state, action</span>) </span>{
  <span class="hljs-keyword">switch</span> (action.type) {
    <span class="hljs-keyword">case</span> <span class="hljs-string">'increment'</span>:
      <span class="hljs-keyword">return</span> { <span class="hljs-attr">count</span>: state.count + <span class="hljs-number">1</span> };
    <span class="hljs-keyword">case</span> <span class="hljs-string">'decrement'</span>:
      <span class="hljs-keyword">return</span> { <span class="hljs-attr">count</span>: state.count - <span class="hljs-number">1</span> };
    <span class="hljs-keyword">default</span>:
      <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>();
  }
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">MyComponent</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [state, dispatch] = useReducer(reducer, { <span class="hljs-attr">count</span>: <span class="hljs-number">0</span> });

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Count: {state.count}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{()</span> =&gt;</span> dispatch({ type: 'increment' })}&gt;Increment<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{()</span> =&gt;</span> dispatch({ type: 'decrement' })}&gt;Decrement<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}
</code></pre>
<ul>
<li><p><code>memo</code> takes a component as its first argument, and an optional <code>compare</code> function as a second argument. The <code>compare</code> function is used to determine if the component should re-render based on the props. If no <code>compare</code> function is provided, <code>memo</code> will use a shallow comparison of the props to determine if the component should re-render.</p>
</li>
<li><p><code>useRef</code> allows you to create a reference to an element or a value in a functional component. It's a way to store a reference to an element or a value that persists between renders.</p>
</li>
</ul>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> { useRef } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">MyComponent</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> inputRef = useRef(<span class="hljs-literal">null</span>);

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">ref</span>=<span class="hljs-string">{inputRef}</span> /&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{()</span> =&gt;</span> inputRef.current.focus()}&gt;Focus Input<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}
</code></pre>
<ul>
<li><p>In summary, <code>useState</code> is used to manage state in a component and <code>useRef</code> is used to create a reference to an element or a value in a component.</p>
</li>
<li><p><code>useState</code> is useful when you need to keep track of a value that can change over time, and you want the component to re-render when that value changes. <code>useRef</code> is useful when you need to access or manipulate an element in the DOM, or if you need to keep track of a value that should persist between renders but does not need to cause a re-render.</p>
</li>
<li><p><code>createContext</code> is an API in React that allows you to create a context, which is a way to share data between components. It allows you to pass data down through a component tree without having to pass props down manually at every level. context refers to a way to share data between components without having to pass props down manually at every level of the component tree.</p>
</li>
</ul>
<h2 id="heading-when-shouldnt-you-use-the-context-api">When shouldn't you use the Context API?</h2>
<p><strong>Everything that consumes a context re-renders every time that context’s state changes.</strong> That means that if you’re consuming your context all over the place in your app, or worse, using one context for your entire app’s state, you’re causing a ton of re-renders all over the place</p>
<h2 id="heading-what-is-a-fragment">What is a Fragment?</h2>
<p>A common pattern in React is for a component to return multiple elements. Fragments <strong>let you group a list of children without adding extra nodes to the DOM</strong>.</p>
<h2 id="heading-what-is-a-portal">What is a portal?</h2>
<p>A portal is a way to render children in a dom node that exists outside the dom hierachy of the parent component and it can live anywhere in the dom tree and you most often in ui components like modal.</p>
<h2 id="heading-what-are-uncontrolled-and-controlled-components">What are uncontrolled and controlled components?</h2>
<p>A controlled component in React is when the component's state directly controls the value of form elements. Changes to the form elements are managed through React's event handlers.
Uncontrolled are input values which are typically controlled by users and react does not control.</p>
</br><p style="color:#757CF9;">This article is published w/ <a target="_blank" href="https://scattr.io?ref=dev">Scattr  ↗️</a></p>