<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ hooks - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ hooks - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Tue, 19 May 2026 04:43:16 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/hooks/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ Learn Flutter Hooks – Common Hooks Explained with Code Examples ]]>
                </title>
                <description>
                    <![CDATA[ Flutter hooks are powerful functions that streamline state management, side effects handling, and code organization in Flutter applications. Inspired by React hooks, they provide a more concise and modular approach compared to traditional StatefulWid... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/learn-flutter-hooks-with-code-examples/</link>
                <guid isPermaLink="false">68d692ebc473cf19ac469ed3</guid>
                
                    <category>
                        <![CDATA[ Flutter ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Dart ]]>
                    </category>
                
                    <category>
                        <![CDATA[ hooks ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Atuoha Anthony ]]>
                </dc:creator>
                <pubDate>Fri, 26 Sep 2025 13:19:39 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1758892716695/6af49b6f-d088-405a-9c48-57d5db3b0a98.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Flutter hooks are powerful functions that streamline state management, side effects handling, and code organization in Flutter applications. Inspired by React hooks, they provide a more concise and modular approach compared to traditional <code>StatefulWidget</code> and <code>setState</code> patterns.</p>
<p>By the end of this guide, you’ll understand the core hooks in Flutter, how to use them effectively, how to create your own custom hooks, and best practices for using them in real-world projects.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><p><a class="post-section-overview" href="#heading-prerequisites">Prerequisites</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-why-flutter-hooks">Why Flutter Hooks?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-common-flutter-hooks">Common Flutter Hooks</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-how-to-use-the-usestate-hook-in-flutter">How to Use the useState Hook in Flutter</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-use-the-useanimationcontroller-hook-in-flutter">How to Use the useAnimationController Hook in Flutter</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-use-the-useeffect-hook-in-flutter">How to Use the useEffect Hook in Flutter</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-use-the-usememoized-hook-in-flutter">How to Use the useMemoized Hook in Flutter</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-use-the-useref-hook-in-flutter">How to Use the useRef Hook in Flutter</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-use-the-usecallback-hook-in-flutter">How to Use the useCallback Hook in Flutter</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-use-the-usecontext-hook-in-flutter">How to Use the useContext Hook in Flutter</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-use-the-usetexteditingcontroller-hook-in-flutter">How to Use the useTextEditingController Hook in Flutter</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-create-a-custom-hook-in-flutter">How to Create a Custom Hook in Flutter</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-advanced-hooks">Advanced Hooks</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-demonstration-counter-example-with-hooks">Demonstration: Counter Example with Hooks</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-best-practices">Best Practices</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-hooks-vs-stateful-widgets">Hooks vs Stateful Widgets</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-additional-resources">Additional Resources</a></p>
</li>
</ul>
<h2 id="heading-prerequisites">Prerequisites</h2>
<p>Before diving into Flutter hooks, make sure you have the following:</p>
<ul>
<li><p><strong>Flutter SDK</strong>: Installed and configured (Flutter 3.x or higher recommended). Verify with:</p>
<pre><code class="lang-bash">  flutter --version
</code></pre>
</li>
<li><p><strong>Dart SDK</strong>: Comes with Flutter, ensure it’s up to date.</p>
</li>
<li><p><strong>IDE</strong>: Visual Studio Code, Android Studio, or IntelliJ with Flutter extensions.</p>
</li>
<li><p><strong>Basic Flutter knowledge</strong>: Familiarity with widgets, <code>StatelessWidget</code>, <code>StatefulWidget</code>, and state management basics.</p>
</li>
<li><p><strong>Package dependency</strong>: The <code>flutter_hooks</code> package installed by adding the following to <code>pubspec.yaml</code>:</p>
<pre><code class="lang-yaml">  <span class="hljs-attr">dependencies:</span>
    <span class="hljs-attr">flutter_hooks:</span> <span class="hljs-string">^0.21.3+1</span>
</code></pre>
<p>  Then run:</p>
<pre><code class="lang-bash">  flutter pub get
</code></pre>
</li>
</ul>
<h2 id="heading-why-flutter-hooks">Why Flutter Hooks?</h2>
<p>Here are some of the benefits of using Flutter hooks:</p>
<ol>
<li><p><strong>Improved Readability and Maintainability</strong><br> Hooks reduce boilerplate by embedding state and side effects logic directly in the widget’s build method. This makes the code cleaner and easier to understand.</p>
</li>
<li><p><strong>Reusability</strong><br> Hooks can be abstracted into custom hooks. For example, you could extract complex logic (like data fetching) into a reusable function.</p>
</li>
<li><p><strong>Granular State Management</strong><br> Instead of managing a single <code>State</code> object for an entire widget, hooks let you manage small, independent pieces of state. This is especially useful for complex UIs.</p>
</li>
<li><p><strong>Simplified Side Effects</strong><br> Hooks such as <code>useEffect</code> provide an elegant way to handle lifecycle-related tasks like data fetching, listeners, or subscriptions.</p>
</li>
</ol>
<h2 id="heading-common-flutter-hooks">Common Flutter Hooks</h2>
<p>Let’s go through the most common hooks, with explanations line by line.</p>
<h3 id="heading-how-to-use-the-usestate-hook-in-flutter">How to Use the <code>useState</code> Hook in Flutter</h3>
<p>The simplest and most used hook. It allows you to declare and manage state inside a <code>HookWidget</code>.</p>
<pre><code class="lang-dart"><span class="hljs-keyword">import</span> <span class="hljs-string">'package:flutter/material.dart'</span>;
<span class="hljs-keyword">import</span> <span class="hljs-string">'package:flutter_hooks/flutter_hooks.dart'</span>;

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">CounterButton</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">HookWidget</span> </span>{
  <span class="hljs-meta">@override</span>
  Widget build(BuildContext context) {
    <span class="hljs-keyword">final</span> counter = useState&lt;<span class="hljs-built_in">int</span>&gt;(<span class="hljs-number">0</span>); <span class="hljs-comment">// Step 1: create state with initial value 0</span>

    <span class="hljs-keyword">return</span> ElevatedButton(
      onPressed: () =&gt; counter.value++, <span class="hljs-comment">// Step 2: update state using counter.value</span>
      child: Text(<span class="hljs-string">'Count: <span class="hljs-subst">${counter.value}</span>'</span>), <span class="hljs-comment">// Step 3: read the state</span>
    );
  }
}
</code></pre>
<p><strong>Explanation</strong></p>
<ul>
<li><p><code>useState&lt;int&gt;(0)</code> initializes state with a value of <code>0</code>.</p>
</li>
<li><p><code>counter.value</code> reads the state.</p>
</li>
<li><p>Updating <code>counter.value</code> triggers a rebuild, just like <code>setState</code>.</p>
</li>
</ul>
<h3 id="heading-how-to-use-the-useanimationcontroller-hook-in-flutter">How to Use the <code>useAnimationController</code> Hook in Flutter</h3>
<p>Handles animations while managing the controller’s lifecycle automatically.</p>
<pre><code class="lang-dart"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">AnimatedBox</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">HookWidget</span> </span>{
  <span class="hljs-meta">@override</span>
  Widget build(BuildContext context) {
    <span class="hljs-keyword">final</span> controller = useAnimationController(
      duration: <span class="hljs-keyword">const</span> <span class="hljs-built_in">Duration</span>(seconds: <span class="hljs-number">1</span>), <span class="hljs-comment">// Step 1: define animation duration</span>
    );

    <span class="hljs-keyword">return</span> FadeTransition(
      opacity: controller, <span class="hljs-comment">// Step 2: bind controller to animation</span>
      child: Container(width: <span class="hljs-number">100</span>, height: <span class="hljs-number">100</span>, color: Colors.blue),
    );
  }
}
</code></pre>
<p><strong>Explanation</strong></p>
<ul>
<li><p>The hook creates an <code>AnimationController</code> that lasts 1 second.</p>
</li>
<li><p>The controller is automatically disposed of when the widget is removed.</p>
</li>
<li><p>You can trigger animations with <code>controller.forward()</code> or <code>controller.reverse()</code>.</p>
</li>
</ul>
<h3 id="heading-how-to-use-the-useeffect-hook-in-flutter">How to Use the <code>useEffect</code> Hook in Flutter</h3>
<p>Handles side effects such as fetching data or setting up listeners.</p>
<pre><code class="lang-dart"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">DataWidget</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">HookWidget</span> </span>{
  <span class="hljs-meta">@override</span>
  Widget build(BuildContext context) {
    useEffect(() {
      fetchData(); <span class="hljs-comment">// Step 1: perform side effect</span>
      <span class="hljs-keyword">return</span> () =&gt; cancelSubscription(); <span class="hljs-comment">// Step 2: optional cleanup</span>
    }, []); <span class="hljs-comment">// Step 3: dependency list</span>

    <span class="hljs-keyword">return</span> Text(<span class="hljs-string">'Data is loading...'</span>);
  }
}
</code></pre>
<p><strong>Explanation</strong></p>
<ul>
<li><p>The callback runs when the widget builds.</p>
</li>
<li><p>The cleanup function runs when the widget is disposed or dependencies change.</p>
</li>
<li><p>The empty dependency list <code>[]</code> means it only runs once.</p>
</li>
</ul>
<h3 id="heading-how-to-use-the-usememoized-hook-in-flutter">How to Use the <code>useMemoized</code> Hook in Flutter</h3>
<p>Caches expensive computations and reuses results unless dependencies change.</p>
<pre><code class="lang-dart"><span class="hljs-keyword">final</span> calculatedValue = useMemoized(() =&gt; calculateExpensiveValue(), []);
</code></pre>
<p><strong>Explanation</strong></p>
<ul>
<li><p><code>calculateExpensiveValue()</code> runs once and caches the result.</p>
</li>
<li><p>With dependencies provided, the function reruns only when they change.</p>
</li>
</ul>
<h3 id="heading-how-to-use-the-useref-hook-in-flutter">How to Use the <code>useRef</code> Hook in Flutter</h3>
<p>Keeps a mutable reference across rebuilds.</p>
<pre><code class="lang-dart"><span class="hljs-keyword">final</span> textController = useRef(TextEditingController());

TextFormField(
  controller: textController.value,
  decoration: InputDecoration(labelText: <span class="hljs-string">'Username'</span>),
);
</code></pre>
<p><strong>Explanation</strong></p>
<ul>
<li><p><code>useRef</code> stores an object without triggering rebuilds.</p>
</li>
<li><p>Useful for controllers, focus nodes, or mutable values that shouldn’t reset.</p>
</li>
</ul>
<h3 id="heading-how-to-use-the-usecallback-hook-in-flutter">How to Use the <code>useCallback</code> Hook in Flutter</h3>
<p>Memoizes a callback to prevent unnecessary widget rebuilds.</p>
<pre><code class="lang-dart"><span class="hljs-keyword">final</span> onPressed = useCallback(() =&gt; <span class="hljs-built_in">print</span>(<span class="hljs-string">'Pressed'</span>), []);
</code></pre>
<p><strong>Explanation</strong></p>
<ul>
<li><p>Without <code>useCallback</code>, functions may be recreated on each rebuild.</p>
</li>
<li><p>Memoized callbacks improve performance when passed to widgets like <code>ListView</code>.</p>
</li>
</ul>
<h3 id="heading-how-to-use-the-usecontext-hook-in-flutter">How to Use the <code>useContext</code> Hook in Flutter</h3>
<p>Provides direct access to <code>BuildContext</code> values like themes or providers.</p>
<pre><code class="lang-dart"><span class="hljs-keyword">final</span> theme = useContext();
</code></pre>
<h3 id="heading-how-to-use-the-usetexteditingcontroller-hook-in-flutter">How to Use the <code>useTextEditingController</code> Hook in Flutter</h3>
<p>A shorthand for creating text controllers.</p>
<pre><code class="lang-dart"><span class="hljs-keyword">final</span> usernameController = useTextEditingController();

TextFormField(
  controller: usernameController,
  decoration: InputDecoration(labelText: <span class="hljs-string">'Username'</span>),
);
</code></pre>
<p><strong>Explanation:</strong></p>
<h3 id="heading-1-what-is-usetexteditingcontroller">1. <strong>What is</strong> <code>useTextEditingController()</code>?</h3>
<pre><code class="lang-dart"><span class="hljs-keyword">final</span> usernameController = useTextEditingController();
</code></pre>
<ul>
<li><p>Normally in Flutter, if you want to manage text input, you create a <code>TextEditingController</code>.</p>
</li>
<li><p>With a normal <code>StatefulWidget</code>, you’d do something like:</p>
</li>
</ul>
<pre><code class="lang-dart"><span class="hljs-keyword">late</span> TextEditingController usernameController;

<span class="hljs-meta">@override</span>
<span class="hljs-keyword">void</span> initState() {
  <span class="hljs-keyword">super</span>.initState();
  usernameController = TextEditingController();
}

<span class="hljs-meta">@override</span>
<span class="hljs-keyword">void</span> dispose() {
  usernameController.dispose();
  <span class="hljs-keyword">super</span>.dispose();
}
</code></pre>
<ul>
<li><p>But with <strong>Flutter Hooks</strong>, you can replace all that boilerplate with:</p>
<pre><code class="lang-dart">  <span class="hljs-keyword">final</span> usernameController = useTextEditingController();
</code></pre>
</li>
<li><p>This hook automatically:</p>
<ul>
<li><p><strong>Creates</strong> the controller.</p>
</li>
<li><p><strong>Keeps it alive</strong> for as long as the widget exists.</p>
</li>
<li><p><strong>Disposes</strong> of it when the widget is destroyed.<br>  So you don’t need to manage lifecycle manually anymore.</p>
</li>
</ul>
</li>
</ul>
<h3 id="heading-2-using-the-controller-in-a-textformfield">2. <strong>Using the controller in a</strong> <code>TextFormField</code></h3>
<pre><code class="lang-dart">TextFormField(
  controller: usernameController,
  decoration: InputDecoration(labelText: <span class="hljs-string">'Username'</span>),
);
</code></pre>
<ul>
<li><p>This <code>TextFormField</code> is linked to the <code>usernameController</code>.</p>
</li>
<li><p>Whatever the user types in the input field will be stored in <code>usernameController.text</code>.</p>
</li>
<li><p>You can read or modify it at any time:</p>
<pre><code class="lang-dart">  <span class="hljs-built_in">print</span>(usernameController.text);  <span class="hljs-comment">// get typed text</span>
  usernameController.text = <span class="hljs-string">"Anthony"</span>; <span class="hljs-comment">// set default value</span>
</code></pre>
</li>
</ul>
<h3 id="heading-3-how-it-works-together">3. <strong>How it works together</strong></h3>
<ul>
<li><p><code>useTextEditingController()</code> provides a ready-to-use <code>TextEditingController</code> without the hassle of init/dispose.</p>
</li>
<li><p>The <code>TextFormField</code> uses this controller to manage user input.</p>
</li>
<li><p>This is the <strong>hooks way</strong> of handling text fields.</p>
</li>
</ul>
<p><strong>Summary</strong></p>
<ul>
<li><p><code>useTextEditingController()</code> → Hook to create &amp; dispose a <code>TextEditingController</code> automatically.</p>
</li>
<li><p><code>TextFormField(controller: ...)</code> → Uses that controller to manage and access the text typed in the field.</p>
</li>
<li><p>Cleaner and safer than manually handling init/dispose in a <code>StatefulWidget</code>.</p>
</li>
</ul>
<h2 id="heading-how-to-create-a-custom-hook-in-flutter">How to Create a Custom Hook in Flutter</h2>
<p>You can encapsulate logic in reusable hooks.</p>
<pre><code class="lang-dart">Future&lt;<span class="hljs-built_in">String</span>&gt; useFetchData() {
  <span class="hljs-keyword">final</span> data = useState&lt;<span class="hljs-built_in">String</span>&gt;(<span class="hljs-string">'Loading...'</span>);

  useEffect(() {
    Future.microtask(() <span class="hljs-keyword">async</span> {
      data.value = <span class="hljs-keyword">await</span> fetchDataFromApi();
    });
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">null</span>;
  }, []);

  <span class="hljs-keyword">return</span> data.value;
}
</code></pre>
<p><strong>Explanation:</strong></p>
<h3 id="heading-1-function-signature">1. <strong>Function signature</strong></h3>
<pre><code class="lang-dart">Future&lt;<span class="hljs-built_in">String</span>&gt; useFetchData()
</code></pre>
<p>At first glance, it looks like this function should return a <code>Future&lt;String&gt;</code>.<br>But in reality, the function does not return a <code>Future</code>, it returns <code>data.value</code>, which is a <code>String</code>.</p>
<p>So the correct signature should really be:</p>
<pre><code class="lang-dart"><span class="hljs-built_in">String</span> useFetchData()
</code></pre>
<p>Because what you’re returning is the current state of the data, not a <code>Future</code>.</p>
<h3 id="heading-2-state-setup">2. <strong>State setup</strong></h3>
<pre><code class="lang-dart"><span class="hljs-keyword">final</span> data = useState&lt;<span class="hljs-built_in">String</span>&gt;(<span class="hljs-string">'Loading...'</span>);
</code></pre>
<ul>
<li><p>This creates a state variable <code>data</code> with an initial value of <code>"Loading..."</code>.</p>
</li>
<li><p><code>data.value</code> holds the actual string value.</p>
</li>
<li><p>Updating <code>data.value</code> will cause the widget to rebuild.</p>
</li>
</ul>
<h3 id="heading-3-effect-hook">3. <strong>Effect hook</strong></h3>
<pre><code class="lang-dart">useEffect(() {
  Future.microtask(() <span class="hljs-keyword">async</span> {
    data.value = <span class="hljs-keyword">await</span> fetchDataFromApi();
  });
  <span class="hljs-keyword">return</span> <span class="hljs-keyword">null</span>;
}, []);
</code></pre>
<ul>
<li><p><code>useEffect</code> runs once (because the dependency list <code>[]</code> is empty).</p>
</li>
<li><p>Inside it, a <code>Future.microtask</code> schedules an async task to fetch data.</p>
</li>
<li><p>Once the API call finishes, <code>data.value</code> is updated with the response from <code>fetchDataFromApi()</code>.</p>
</li>
<li><p>Updating <code>data.value</code> triggers a rebuild, so the UI will now show the new data instead of <code>"Loading..."</code>.</p>
</li>
</ul>
<h3 id="heading-4-return-value">4. <strong>Return value</strong></h3>
<pre><code class="lang-dart"><span class="hljs-keyword">return</span> data.value;
</code></pre>
<ul>
<li><p>This returns the current state value (<code>'Loading...'</code> initially, later replaced by the fetched data).</p>
</li>
<li><p>On first build, you’ll get <code>"Loading..."</code>.</p>
</li>
<li><p>After the API call finishes, a rebuild happens and now <code>useFetchData()</code> will return the fetched string.</p>
</li>
</ul>
<h3 id="heading-5-how-it-works-in-practice">5. <strong>How it works in practice</strong></h3>
<p>Imagine this widget code:</p>
<pre><code class="lang-dart"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MyWidget</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">HookWidget</span> </span>{
  <span class="hljs-meta">@override</span>
  Widget build(BuildContext context) {
    <span class="hljs-keyword">final</span> result = useFetchData();

    <span class="hljs-keyword">return</span> Text(result); 
  }
}
</code></pre>
<p><strong>Step 1</strong> → UI shows <code>"Loading..."</code>.<br><strong>Step 2</strong> → API is called in the background.<br><strong>Step 3</strong> → When the API response arrives, <code>data.value</code> updates.<br><strong>Step 4</strong> → Widget rebuilds and now <code>Text(result)</code> displays the fetched data.</p>
<p><strong>Summary</strong></p>
<ul>
<li><p><code>useState</code> holds the data (<code>Loading...</code> → fetched result).</p>
</li>
<li><p><code>useEffect</code> runs once to trigger the async fetch.</p>
</li>
<li><p>When the fetch finishes, it updates state → widget rebuilds → UI shows new value.</p>
</li>
<li><p>The function should return a <code>String</code>, not <code>Future&lt;String&gt;</code>.</p>
</li>
</ul>
<h2 id="heading-advanced-hooks">Advanced Hooks</h2>
<ul>
<li><p><code>useListenable</code>: Works with <code>ValueNotifier</code> or <code>ChangeNotifier</code>.</p>
</li>
<li><p><code>useDebounced</code>: Debounces input, useful for search fields.</p>
</li>
<li><p><code>usePreviousState</code> (from community libraries): Keeps track of the previous value.</p>
</li>
</ul>
<h2 id="heading-demonstration-counter-example-with-hooks">Demonstration: Counter Example with Hooks</h2>
<pre><code class="lang-dart"><span class="hljs-keyword">import</span> <span class="hljs-string">'package:flutter/material.dart'</span>;
<span class="hljs-keyword">import</span> <span class="hljs-string">'package:flutter_hooks/flutter_hooks.dart'</span>;

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Counter</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">HookWidget</span> </span>{
  <span class="hljs-meta">@override</span>
  Widget build(BuildContext context) {
    <span class="hljs-keyword">final</span> count = useState&lt;<span class="hljs-built_in">int</span>&gt;(<span class="hljs-number">0</span>); <span class="hljs-comment">// state variable initialized to 0</span>

    useEffect(() {
      <span class="hljs-built_in">print</span>(<span class="hljs-string">'Count updated: <span class="hljs-subst">${count.value}</span>'</span>); <span class="hljs-comment">// log whenever count changes</span>
      <span class="hljs-keyword">return</span> <span class="hljs-keyword">null</span>; <span class="hljs-comment">// no cleanup needed</span>
    }, [count.value]); <span class="hljs-comment">// dependency: re-run when count changes</span>

    <span class="hljs-keyword">return</span> Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        Text(<span class="hljs-string">'You clicked <span class="hljs-subst">${count.value}</span> times'</span>, style: TextStyle(fontSize: <span class="hljs-number">24</span>)),
        ElevatedButton(
          onPressed: () =&gt; count.value++, <span class="hljs-comment">// increment state</span>
          child: Text(<span class="hljs-string">'Increment'</span>),
        ),
      ],
    );
  }
}
</code></pre>
<p><strong>Explanation:</strong></p>
<p>This code is using the <code>flutter_hooks</code> package to manage state and lifecycle in a functional style instead of the usual <code>StatefulWidget</code> + <code>setState</code>. Let’s break it down step by step:</p>
<h3 id="heading-1-class-definition">1. <strong>Class definition</strong></h3>
<pre><code class="lang-dart"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Counter</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">HookWidget</span> </span>{
  <span class="hljs-meta">@override</span>
  Widget build(BuildContext context) {
    ...
  }
}
</code></pre>
<ul>
<li><p><code>Counter</code> extends <code>HookWidget</code> instead of <code>StatelessWidget</code> or <code>StatefulWidget</code>.</p>
</li>
<li><p><code>HookWidget</code> allows you to use hooks (like <code>useState</code>, <code>useEffect</code>) directly inside the <code>build</code> method to manage state and side effects.</p>
</li>
</ul>
<h3 id="heading-2-state-with-usestate">2. <strong>State with</strong> <code>useState</code></h3>
<pre><code class="lang-dart"><span class="hljs-keyword">final</span> count = useState&lt;<span class="hljs-built_in">int</span>&gt;(<span class="hljs-number">0</span>);
</code></pre>
<ul>
<li><p><code>useState</code> is a hook that creates a piece of state.</p>
</li>
<li><p>Here, it initializes <code>count</code> with <code>0</code>.</p>
</li>
<li><p><code>count</code> is not just an <code>int</code>, but a <code>ValueNotifier&lt;int&gt;</code> (meaning you can read <code>count.value</code> and update it by assigning to <code>count.value</code>).</p>
</li>
</ul>
<p>So initially:<br><code>count.value = 0</code>.</p>
<h3 id="heading-3-effect-with-useeffect">3. <strong>Effect with</strong> <code>useEffect</code></h3>
<pre><code class="lang-dart">useEffect(() {
  <span class="hljs-built_in">print</span>(<span class="hljs-string">'Count updated: <span class="hljs-subst">${count.value}</span>'</span>);
  <span class="hljs-keyword">return</span> <span class="hljs-keyword">null</span>;
}, [count.value]);
</code></pre>
<ul>
<li><p><code>useEffect</code> is used to perform side effects whenever dependencies change.</p>
</li>
<li><p>In this case, it runs whenever <code>count.value</code> changes.</p>
</li>
<li><p>It prints the updated value to the console each time the counter changes.</p>
</li>
<li><p>The second argument <code>[count.value]</code> is the dependency list (like React Hooks). If <code>count.value</code> changes, this effect runs again.</p>
</li>
</ul>
<h3 id="heading-4-ui">4. <strong>UI</strong></h3>
<pre><code class="lang-dart"><span class="hljs-keyword">return</span> Column(
  mainAxisAlignment: MainAxisAlignment.center,
  children: [
    Text(<span class="hljs-string">'You clicked <span class="hljs-subst">${count.value}</span> times'</span>, style: TextStyle(fontSize: <span class="hljs-number">24</span>)),
    ElevatedButton(
      onPressed: () =&gt; count.value++, <span class="hljs-comment">// increment state</span>
      child: Text(<span class="hljs-string">'Increment'</span>),
    ),
  ],
);
</code></pre>
<ul>
<li><p>A <code>Column</code> displays two widgets:</p>
<ol>
<li><p>A <code>Text</code> widget showing the number of times the button has been clicked.</p>
</li>
<li><p>An <code>ElevatedButton</code> that increments the counter when pressed (<code>count.value++</code>).</p>
</li>
</ol>
</li>
</ul>
<p>Because <code>count</code> is a <code>ValueNotifier</code>, updating <code>count.value</code> automatically triggers a rebuild of the widget.</p>
<h3 id="heading-5-how-it-works-in-practice-1">5. <strong>How it works in practice</strong></h3>
<ol>
<li><p>The app shows: "You clicked 0 times" and a button "Increment".</p>
</li>
<li><p>When you tap the button:</p>
<ul>
<li><p><code>count.value</code> increases by 1.</p>
</li>
<li><p>The widget rebuilds, showing the updated count.</p>
</li>
<li><p><code>useEffect</code> runs, printing <code>Count updated: X</code> to the console.</p>
</li>
</ul>
</li>
</ol>
<p><strong>Summary:</strong><br>This code is a counter app built using Flutter Hooks.</p>
<ul>
<li><p><code>useState</code> manages the counter state.</p>
</li>
<li><p><code>useEffect</code> listens for changes in the counter and runs a side effect (printing to console).</p>
</li>
<li><p>The UI displays the count and a button to increment it.</p>
</li>
</ul>
<h2 id="heading-best-practices">Best Practices</h2>
<ul>
<li><p><strong>Use dependency lists correctly</strong> with <code>useEffect</code> and <code>useMemoized</code>.</p>
</li>
<li><p><strong>Don’t over-engineer</strong>: Sometimes <code>StatefulWidget</code> is simpler.</p>
</li>
<li><p><strong>Test thoroughly</strong>, especially when side effects are involved.</p>
</li>
<li><p><strong>Extract reusable logic</strong> into custom hooks to keep widgets focused.</p>
</li>
</ul>
<h2 id="heading-hooks-vs-stateful-widgets">Hooks vs Stateful Widgets</h2>
<h3 id="heading-what-are-stateful-widgets"><strong>What are Stateful Widgets?</strong></h3>
<p>A StatefulWidget is a widget that can change over time because it holds mutable state.</p>
<ul>
<li><p>It’s made up of two classes:</p>
<ol>
<li><p><code>StatefulWidget</code> → the immutable configuration.</p>
</li>
<li><p><code>State&lt;T&gt;</code> → the mutable state and logic.</p>
</li>
</ol>
</li>
</ul>
<h3 id="heading-how-they-work"><strong>How they work</strong></h3>
<ul>
<li><p>When something in the state changes, you call <code>setState()</code>.</p>
</li>
<li><p>This tells Flutter to rebuild the widget tree with the updated state.</p>
</li>
</ul>
<p>Example:</p>
<pre><code class="lang-dart"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Counter</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">StatefulWidget</span> </span>{
  <span class="hljs-meta">@override</span>
  _CounterState createState() =&gt; _CounterState();
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">_CounterState</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">State</span>&lt;<span class="hljs-title">Counter</span>&gt; </span>{
  <span class="hljs-built_in">int</span> count = <span class="hljs-number">0</span>;

  <span class="hljs-meta">@override</span>
  Widget build(BuildContext context) {
    <span class="hljs-keyword">return</span> Column(
      children: [
        Text(<span class="hljs-string">'You clicked <span class="hljs-subst">$count</span> times'</span>),
        ElevatedButton(
          onPressed: () =&gt; setState(() =&gt; count++),
          child: Text(<span class="hljs-string">'Increment'</span>),
        ),
      ],
    );
  }
}
</code></pre>
<h3 id="heading-key-points"><strong>Key points</strong></h3>
<ul>
<li><p>Good for simple UI state (like counters, toggles, form fields).</p>
</li>
<li><p>Flutter manages the widget’s lifecycle (init, rebuild, dispose).</p>
</li>
<li><p>You handle initialization in <code>initState</code> and cleanup in <code>dispose</code>.</p>
</li>
</ul>
<p><strong>In short:</strong><br>Stateful widgets are the <em>classic way</em> to manage state in Flutter. They’re straightforward for beginners and great for simple use cases. For more complex or reusable state logic, hooks (or state management libraries like BLoC, Riverpod) can be cleaner and more scalable.</p>
<p><strong>Summary:</strong></p>
<ul>
<li><p><strong>Hooks</strong>: Cleaner, modular, reusable, great for advanced state handling.</p>
</li>
<li><p><strong>Stateful Widgets</strong>: Easier for beginners and fine for simple state.</p>
</li>
</ul>
<h2 id="heading-additional-resources">Additional Resources</h2>
<ul>
<li><a target="_blank" href="https://pub.dev/packages/flutter_hooks">flutter_hooks package on pub.dev</a></li>
</ul>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ React Hooks – How to Use the useState & useEffect Hooks in Your Project ]]>
                </title>
                <description>
                    <![CDATA[ Hooks allow function components to have access to state and other React features, such as lifecycle methods. These Hook features were introduced to React version 16.8. One of the interesting things about the Hook features is that they let you use Rea... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-use-the-usestate-and-useeffect-hooks-in-your-project/</link>
                <guid isPermaLink="false">66d45e0c47a8245f78752a26</guid>
                
                    <category>
                        <![CDATA[ hooks ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                    <category>
                        <![CDATA[ react hooks ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Okoro Emmanuel Nzube ]]>
                </dc:creator>
                <pubDate>Fri, 08 Mar 2024 15:37:42 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/03/React-JS-Hooks.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Hooks allow function components to have access to state and other React features, such as lifecycle methods. These Hook features were introduced to React version 16.8.</p>
<p>One of the interesting things about the Hook features is that they let you use React without classes. This, in turn, helps simplify your codebase and helps you write cleaner and more intuitive code.</p>
<p>In this article, you will learn how to make use of the common Hooks in your project.</p>
<h2 id="heading-react-hooks-benefits">React Hooks Benefits</h2>
<p>Let's go over some of the reasons why you might want to use Hooks in your project:</p>
<ul>
<li><p><strong>Easy to use and understand:</strong> With Hooks, you can write more straightforward code. These Hook commands can only be written inside a functional component.</p>
</li>
<li><p><strong>Reusable code:</strong> Hooks allow you to reuse a particular logic used in one component across multiple other components.</p>
</li>
<li><p><strong>Better optimization performance:</strong> Hooks offer a more efficient approach to utilizing React functionalities like state and lifecycle functions, resulting in improved performance as compared to class components in some situations.</p>
</li>
</ul>
<h2 id="heading-different-types-of-react-hooks">Different Types of React Hooks</h2>
<p>The React Hook features are of different types, ranging from the <code>useState</code>, <code>useEffect</code>, <code>useRef</code>, <code>useReducer</code>, and so on.</p>
<h2 id="heading-react-hook-rules">React Hook Rules</h2>
<p>There are a few important rules when it comes to the React Hook features that should be strictly followed. Let's go over them in the following sections.</p>
<h3 id="heading-hooks-should-be-called-inside-a-react-function">Hooks should be called inside a React function</h3>
<p>Hooks should not be used inside a class component – they can and should only be called inside the React function.</p>
<p>This first rule essentially specifies that a Hook component should not be found in a class component, but in a functional component.</p>
<p>Here is the wrong way of implementing the Hook feature:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> React, { Component } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
<span class="hljs-keyword">import</span> React, {useState} <span class="hljs-keyword">from</span> react;

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

  render() {
    <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">h1</span>&gt;</span>Hello, I am a Class Component!<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
    );
  }
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> App;
</code></pre>
<p>And here is the correct way of implementing the Hook feature:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> React, { 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">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [userName, setUsername] = useState(<span class="hljs-string">''</span>);

  };

  <span class="hljs-keyword">return</span> ( Your JSX code goes <span class="hljs-keyword">in</span> here.....);
};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> App;
</code></pre>
<p>The code example above shows a proper way of using a Hook feature.</p>
<p>If you use a Hook feature in a class component, just like in the first example, your code will raise an error. Therefore, you can only implement a Hook inside a function component.</p>
<h3 id="heading-hooks-can-only-be-called-at-the-top-level-of-a-component">Hooks can only be called at the top level of a component</h3>
<p>You can only implement/call a React Hook at the top level of a component before any other code.</p>
<p>Using the code from the previous section as an example, you can see that immediately after <code>function App ()</code>.</p>
<p>The next thing that comes is the Hook command – in that example we used the <code>useState</code> Hook. That is what the second rule is all about.</p>
<h3 id="heading-hooks-cannot-be-used-in-a-conditional-statement">Hooks cannot be used in a conditional statement</h3>
<p>We have different types of conditional statements/rendering ranging from <code>if</code>, <code>else</code>, and so on.</p>
<p>The above rule means that conditionals cannot be applied directly to Hooks. This is the case because Hooks are called in the same order on every render of a functional component.</p>
<p>You can conditionally run Hooks within a functional component, but for this to work, this condition must be determined by top-level logic and should not be nested within any other blocks or components.</p>
<p>The reason for this is because Hooks need to be invoked at the highest level of the component, rather than under conditions, loops, or nested functions.</p>
<p>Here is an example:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> React, { useState, useEffect } <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">ConditionalEffectComponent</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [isMounted, setIsMounted] = useState(<span class="hljs-literal">false</span>);

  useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">if</span> (isMounted) {
      <span class="hljs-comment">// Perform some effect when the component is mounted</span>
      <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Component mounted'</span>);
    }
  }, [isMounted]); <span class="hljs-comment">// Dependency array ensures effect runs when isMounted changes</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">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{()</span> =&gt;</span> setIsMounted(!isMounted)}&gt;
        {isMounted ? 'Unmount' : 'Mount'}
      <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>
  );
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> ConditionalEffectComponent;
</code></pre>
<p>From the example above, the <code>useEffect</code> hook is executed conditionally dependent on the value of the <code>isMounted</code> state variable.</p>
<p>Clicking the button causes the value of <code>isMounted</code> to alternate, either activating or deactivating the effect depending on the updated value.</p>
<p>This is deemed appropriate because the Hook is invoked at the highest level of the component and its condition is determined by the overarching logic within the component.</p>
<h2 id="heading-how-to-use-the-usestate-hook">How to Use the useState Hook</h2>
<p>The React <code>useState</code> Hook enables you to have state variables in functional components.</p>
<p>To make use of the state Hook, you must first import it into your project by using the <code>import</code> command.</p>
<p>The way <code>useState</code> works is that it gives us two variables. The first variable is known as the value of the state, and the second variable is a function used to update the state.</p>
<p>Here is an example of how to go about this:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> <span class="hljs-string">'./App.css'</span>
<span class="hljs-keyword">import</span> React, { 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">App</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>You clicked {count} times<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; Click me
        <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>
    ); 
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> App;
</code></pre>
<p>From the code example above, you can see that the state Hook was used in a functional component and not a class component.</p>
<p><code>count</code> and <code>setCount</code> are the two variables of the state Hook, where <code>count</code> is the current value of the state and <code>setCount</code> is used to update the value of the state. Therefore, whenever the button is clicked, <code>setCount</code> will update the value of the count.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/02/R1.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>How useState Hook works</em></p>
<h2 id="heading-how-to-use-the-useeffect-hook">How to Use the useEffect Hook</h2>
<p>The <code>useEffect</code> hook in React is like a handy tool for functional components. It helps manage tasks that aren't directly related to showing stuff on the screen, like fetching data from the internet, retrieving data from API endpoints, or setting up timers. It can be used to update components even after they've been shown, making your app more dynamic.</p>
<p>Here's a basic example of how <code>useEffect</code> is used to fetch data from an API endpoint:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> React, { useState, useEffect } <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> [data, setData] = useState(<span class="hljs-literal">null</span>);

  useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">const</span> fetchData = <span class="hljs-keyword">async</span> () =&gt; {
      <span class="hljs-keyword">try</span> {
        <span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> fetch(<span class="hljs-string">'https://api.example.com/data'</span>);
        <span class="hljs-keyword">const</span> jsonData = <span class="hljs-keyword">await</span> response.json();
        setData(jsonData);
      } <span class="hljs-keyword">catch</span> (error) {
        <span class="hljs-built_in">console</span>.error(<span class="hljs-string">'Error fetching data:'</span>, error);
      }
    };

    fetchData(); <span class="hljs-comment">// Call the fetchData function when the component mounts or updates</span>

    <span class="hljs-comment">// Cleanup function (optional) to handle unsubscriptions or resource cleanup</span>
    <span class="hljs-keyword">return</span> <span class="hljs-function">() =&gt;</span> {
      <span class="hljs-comment">// Cleanup logic here, if needed</span>
    };
  }, []); <span class="hljs-comment">// Empty dependency array means the effect runs only once after the initial render</span>

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      {/* Render the fetched data */}
      {data &amp;&amp; (
        <span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span>
          {data.map(item =&gt; (
            <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">key</span>=<span class="hljs-string">{item.id}</span>&gt;</span>{item.name}<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
          ))}
        <span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>
      )}
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> MyComponent;
</code></pre>
<p>In the code example above, <code>MyComponent</code> is a functional component which utilizes React hooks, specifically <code>useState</code> and <code>useEffect</code>, to handle state management and execute side effects. The <code>useState</code> hook is used to initialize a state variable called <code>data</code>. This variable will store the data retrieved from an API endpoint.</p>
<p>The <code>useEffect</code> hook is used to request data from the API endpoint once the component initially renders. Within the <code>useEffect</code>, an asynchronous function <code>fetchData</code> is defined to fetch JSON data from the specified API endpoint using the fetch API.</p>
<p>If the data fetching is successful, the returned JSON data is saved in the data state variable using the <code>setData</code> function supplied by the <code>useState</code> hook.</p>
<p>The <code>useEffect</code> hook also optionally returns a cleaning function, which is currently empty but can be used for any necessary cleanup logic.</p>
<p>In the component's JSX, the fetched data is conditionally rendered. If the data is not null, a list <code>&lt;ul&gt;</code> is produced using items extracted from the data array using map.</p>
<p>Finally, the <code>MyComponent</code> function is exported as the default export from the module, allowing it to be imported and utilized in other sections.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>As a developer, React Hooks are a very useful and powerful tool for functional components that make your work easy.</p>
<p>I believe that at this point you now know what a React Hook is and how to use the most popular ones.</p>
<p>Thanks for reading, and happy coding!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Create an Inventory List with React useReducer, Axios, and JSON Server ]]>
                </title>
                <description>
                    <![CDATA[ When it comes to web development, it's hard to ignore React.js. It has been one of the leading user interface libraries for a decade, and it supports a lot of popular frameworks like Next.js in the background. If you are a React developer, you likely... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/create-an-inventory-list-with-react-usereducer-axios-and-json-server/</link>
                <guid isPermaLink="false">66bdffd3422f318982ba47c0</guid>
                
                    <category>
                        <![CDATA[ axios ]]>
                    </category>
                
                    <category>
                        <![CDATA[ hooks ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Tapas Adhikary ]]>
                </dc:creator>
                <pubDate>Thu, 07 Mar 2024 15:33:49 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/03/inventory-list.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>When it comes to web development, it's hard to ignore React.js. It has been one of the leading user interface libraries for a decade, and it supports a lot of popular frameworks like Next.js in the background.</p>
<p>If you are a React developer, you likely appreciate its component-based architecture, uni-directional data binding, huge community support, and the React team's passion for bringing features in front of developers.</p>
<p>If you are just getting started with React or a beginner at it, that's great – there's a complete <a target="_blank" href="https://www.freecodecamp.org/news/react-fundamentals-for-beginners/">React.js roadmap published here</a> on the freeCodeCamp you can check out. And I think you'll find the library a lot easier to learn if you have a solid grip on basic JavaScript foundations.</p>
<p>Irrespective of where you stand with React, the real fun is in building things with it, don't you agree? So I thought of building a simple <code>inventory list</code> to explain a few powerful concepts like complex state management with useReducer. </p>
<p>And while we're doing that, we'll also create a mock API server using <code>JSON Server</code>, we'll use <code>axios</code> to call the API, and finally we'll use the <code>useReducer</code> hook to manage state.</p>
<p>Sounds interesting? Let's do it. If you would also like to check out the video version of this project, here it is: 😊</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/jKyAEj0EvAA" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><a class="post-section-overview" href="#heading-project-setup-with-react-and-tailwindcss">Project Setup with React and TailwindCSS</a></li>
<li><a class="post-section-overview" href="#heading-how-to-setup-a-server-with-json-server">How to Setup a Server with JSON Server</a></li>
<li><a class="post-section-overview" href="#heading-how-to-set-up-and-use-axios">How to Set Up and Use Axios</a></li>
<li><a class="post-section-overview" href="#heading-how-to-use-the-usereducer-hook-from-react">How to Use the useReducer Hook from React</a></li>
<li><a class="post-section-overview" href="#heading-how-to-create-actions">How to Create Actions</a></li>
<li><a class="post-section-overview" href="#heading-how-to-create-an-inventory-reducer">How to Create an Inventory Reducer</a></li>
<li><a class="post-section-overview" href="#heading-how-to-build-the-inventory-list-component">How to Build the Inventory List Component</a></li>
<li><a class="post-section-overview" href="#heading-how-to-use-axios-to-fetch-data-and-dispatch-it-to-the-reducer">How to Use Axios to Fetch Data and Dispatch it to the Reducer</a></li>
<li><a class="post-section-overview" href="#heading-lets-complete-the-jsx-part">Let's Complete the JSX Part</a></li>
<li><a class="post-section-overview" href="#heading-how-to-use-the-inventory-list-in-the-app-component">How to Use the Inventory List in the App Component</a></li>
<li><a class="post-section-overview" href="#heading-wrapping-up">Wrapping Up</a></li>
</ul>
<h2 id="heading-project-setup-with-react-and-tailwindcss">Project Setup with React and TailwindCSS</h2>
<p>Before we do anything else, let's get the project set up. Also, you can follow along with the <a target="_blank" href="https://github.com/atapas/youtube/tree/main/react/27-inventory-useReducer-jsonserver-axios">source code</a> as you read through.</p>
<p>To build this app, we will use React with <code>Vite</code> and <code>TailwindCSS</code>. You can set up these tools by following a few steps from the <a target="_blank" href="https://vitejs.dev/guide/">Vite</a> and <a target="_blank" href="https://tailwindcss.com/docs/guides/vite">TailwindCSS</a> documentation.</p>
<p>But, why not use something that provides everything built together? This will save you time for future React projects as you can use the same infrastructure to create a React projects every time.</p>
<p>Head over to this <a target="_blank" href="https://github.com/atapas/vite-tailwind-react">repository</a> and click on the <code>Use this template</code> button as indicated in the image below. It will help you create a brand new repository out of a template repository with Vite, React, and TailwindCSS configured.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/02/Screenshot-2024-02-12-at-5.25.29-PM.png" alt="Image" width="600" height="400" loading="lazy">
<em>Create a React Project Repository with TailwindCSS and Vite from an Existing Template</em></p>
<p>Now provide a suitable name to your repository (let's call it <code>inventory-list</code> in this article) along with a description. You may chose to keep the repository private if you wish to, otherwise go ahead and create the repository by clicking on the button at the bottom.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/02/Screenshot-2024-02-12-at-5.30.34-PM.png" alt="Image" width="600" height="400" loading="lazy">
<em>Provide the Details of the New Repository</em></p>
<p>That's it. You have a repository with all the basic ingredients to get started. Now, go to the command prompt/terminal and clone the newly created repository:</p>
<pre><code class="lang-bash">git <span class="hljs-built_in">clone</span> &lt;YOUR NEWLY CREATED REPOSITORY URL&gt;
</code></pre>
<p>Change directories to the project directory and install the project dependencies using the following commands:</p>
<pre><code class="lang-bash"><span class="hljs-comment">## Change to the project directory</span>
<span class="hljs-built_in">cd</span> inventory-list

<span class="hljs-comment">## Install dependencies</span>

<span class="hljs-comment">## Using NPM</span>
npm install

<span class="hljs-comment">## Using Yarn</span>
yarn install

<span class="hljs-comment">## Using PNPM</span>
pnpm install
</code></pre>
<p>After the dependencies are installed successfully, execute the following command to run the project on a local server:</p>
<pre><code class="lang-bash"><span class="hljs-comment">## Run the project locally</span>

<span class="hljs-comment">## Using NPM</span>
npm run dev

<span class="hljs-comment">## Using Yarn</span>
yarn dev

<span class="hljs-comment">## Using PNPM</span>
pnpm dev
</code></pre>
<p>Now the project should be running locally and should be accessible on the default URL, <code>http://localhost:5173</code>. You can access the URL on yor browser and import the project source code into your favourite code editor (I use VS Code). We are all set to start the coding.</p>
<h2 id="heading-how-to-setup-a-server-with-json-server">How to Setup a Server with JSON Server</h2>
<p><code>JSON Server</code> is the go-to option when you want to work with fake/mock APIs to serve data of your choice. It is easy to set up and customize to your use case. </p>
<p>Let's set up the JSON Server for our project. The first thing is to install it.</p>
<p>Open a terminal at the root of the project folder and type the following command to install JSON Server:</p>
<pre><code class="lang-shell">## Using NPM
npm install json-server

## Using Yarn
yarn add json-server

## Using PNPM
pnpm install json-server
</code></pre>
<p>JSON Server uses JSON files as the data sources to perform HTTP operations like GET/POST/PUT/PATCH/DELETE. Create a <code>server/database</code> directory under the <code>src/</code> directory. Now create a file called <code>data.json</code> under the <code>src/server/database/</code> with the following content:</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"edibles"</span>: [
    {
      <span class="hljs-attr">"id"</span>: <span class="hljs-number">1</span>,
      <span class="hljs-attr">"picture"</span>: <span class="hljs-string">"🍌"</span>,
      <span class="hljs-attr">"name"</span>: <span class="hljs-string">"Banana"</span>,
      <span class="hljs-attr">"price"</span>: <span class="hljs-number">32</span>,
      <span class="hljs-attr">"quantity"</span>: <span class="hljs-number">200</span>,
      <span class="hljs-attr">"type"</span>: <span class="hljs-string">"fruits"</span>
    },
    {
      <span class="hljs-attr">"id"</span>: <span class="hljs-number">2</span>,
      <span class="hljs-attr">"picture"</span>: <span class="hljs-string">"🍓"</span>,
      <span class="hljs-attr">"name"</span>: <span class="hljs-string">"Strawberry"</span>,
      <span class="hljs-attr">"price"</span>: <span class="hljs-number">52</span>,
      <span class="hljs-attr">"quantity"</span>: <span class="hljs-number">100</span>,
      <span class="hljs-attr">"type"</span>: <span class="hljs-string">"fruits"</span>
    },
    {
      <span class="hljs-attr">"id"</span>: <span class="hljs-number">3</span>,
      <span class="hljs-attr">"picture"</span>: <span class="hljs-string">"🍗"</span>,
      <span class="hljs-attr">"name"</span>: <span class="hljs-string">"Checken"</span>,
      <span class="hljs-attr">"price"</span>: <span class="hljs-number">110</span>,
      <span class="hljs-attr">"quantity"</span>: <span class="hljs-number">190</span>,
      <span class="hljs-attr">"type"</span>: <span class="hljs-string">"foods"</span>,
      <span class="hljs-attr">"sub-type"</span>: <span class="hljs-string">"Non-Veg"</span>
    },
    {
      <span class="hljs-attr">"id"</span>: <span class="hljs-number">4</span>,
      <span class="hljs-attr">"picture"</span>: <span class="hljs-string">"🥬"</span>,
      <span class="hljs-attr">"name"</span>: <span class="hljs-string">"Lettuce"</span>,
      <span class="hljs-attr">"price"</span>: <span class="hljs-number">12</span>,
      <span class="hljs-attr">"quantity"</span>: <span class="hljs-number">50</span>,
      <span class="hljs-attr">"type"</span>: <span class="hljs-string">"Vegetables"</span>
    },
    {
      <span class="hljs-attr">"id"</span>: <span class="hljs-number">5</span>,
      <span class="hljs-attr">"picture"</span>: <span class="hljs-string">"🍅"</span>,
      <span class="hljs-attr">"name"</span>: <span class="hljs-string">"Tomato"</span>,
      <span class="hljs-attr">"price"</span>: <span class="hljs-number">31</span>,
      <span class="hljs-attr">"quantity"</span>: <span class="hljs-number">157</span>,
      <span class="hljs-attr">"type"</span>: <span class="hljs-string">"Vegetables"</span>
    },
    {
      <span class="hljs-attr">"id"</span>: <span class="hljs-number">6</span>,
      <span class="hljs-attr">"picture"</span>: <span class="hljs-string">"🥩"</span>,
      <span class="hljs-attr">"name"</span>: <span class="hljs-string">"Mutton"</span>,
      <span class="hljs-attr">"price"</span>: <span class="hljs-number">325</span>,
      <span class="hljs-attr">"quantity"</span>: <span class="hljs-number">90</span>,
      <span class="hljs-attr">"type"</span>: <span class="hljs-string">"Non-Veg"</span>
    },
    {
      <span class="hljs-attr">"id"</span>: <span class="hljs-number">7</span>,
      <span class="hljs-attr">"picture"</span>: <span class="hljs-string">"🥕"</span>,
      <span class="hljs-attr">"name"</span>: <span class="hljs-string">"Carrot"</span>,
      <span class="hljs-attr">"price"</span>: <span class="hljs-number">42</span>,
      <span class="hljs-attr">"quantity"</span>: <span class="hljs-number">190</span>,
      <span class="hljs-attr">"type"</span>: <span class="hljs-string">"Vegetables"</span>
    }
  ]
}
</code></pre>
<p>The <code>data.json</code> file contains an array of edible items. Each of the items in the array has properties like picture, name, price, quantity, and type to show in the inventory list.</p>
<p>The last thing left is to add a script into the <code>package.json</code> file so that we can start the JSON Server easily every time. Open the package.json file and add this line inside the <code>scripts</code> object like this:</p>
<pre><code class="lang-json"><span class="hljs-string">"start-server"</span>: <span class="hljs-string">"json-server --watch ./src/server/database/data.json"</span>
</code></pre>
<p>Next, go to the terminal and use the following command to start the JSON Server to serve the API:</p>
<pre><code class="lang-shell">## Using NPM
npm run start-server

## Using Yarn
yarn start-server

## Using PNPM
pnpm run start-server
</code></pre>
<p>You should see a message like this in your terminal:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/03/Screenshot-2024-03-07-at-8.46.32-AM-1.png" alt="Image" width="600" height="400" loading="lazy">
<em>The Output</em></p>
<p>It indicates that the JSON Server is running locally on <code>localhost:3000</code> and there is an API endpoint called <code>edibles</code> serves the data. Now you can access the URL <code>http://localhost:3000/edibles</code> from your browser to see the data (fetched by a GET method call):</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/03/image-32.png" alt="Image" width="600" height="400" loading="lazy">
<em>The API Output</em></p>
<p>Great! Now we have the <code>/edibles</code> API endpoint ready to consume into the React component.</p>
<h2 id="heading-how-to-set-up-and-use-axios">How to Set Up and Use Axios</h2>
<p><code>Axios</code> is an HTTP client that helps us make promise-based asynchronous calls from the browser and Node.js environment. It has a number of <a target="_blank" href="https://www.npmjs.com/package/axios#features">useful features</a> that make it one of the most used libraries for asynchronous request-response.</p>
<p>Note that we could have used the <code>fetch Web API</code> from JavaScript instead of <code>Axios</code> in this project. The only reason for using Axios here is to introduce it progressively. In the future articles, you'll learn its usages in handling JWT tokens from a React application. Stay tuned!</p>
<p>Open the terminal at the root of the project folder and use the following command to install Axios:</p>
<pre><code class="lang-shell">## Using NPM
npm install axios

## Using Yarn
yarn add axios

## Using PNPM
pnpm install axios
</code></pre>
<p>That's it. We will use Axios in a bit after laying out the basic components needed for the inventory list.</p>
<h2 id="heading-how-to-use-the-usereducer-hook-from-react">How to Use the useReducer Hook from React</h2>
<p>React is a user interface library that supports component-based architecture at the core. A component is a single entity that's supposed to perform one task well. Multiple components come together to compose the final user interface.</p>
<p>Often, a component will have its own private data. We call these the <code>states</code> of a component. The value of a state drives the behaviour and appearance of a component. When state changes, the component re-renders to keep itself up-to-date with the latest state value.</p>
<p>The traditional way of handling state in React is with the <code>useState</code> hook. It works great as long as your state changes are trivial. As the state change logic becomes more complex and if you need to manage multiple scenarios around it, <code>useState</code> may make things clumsy. This is where you should think about using the <code>useReducer</code> hook.</p>
<p><code>useReducer</code> is a standard hook from the React library. It accepts two primary parameters:</p>
<ul>
<li><code>initState</code>: the initial state value</li>
<li><code>reducer</code>: a JavaScript function that holds the state change logic based on an action (or trigger).</li>
</ul>
<p>The hook returns the following:</p>
<ul>
<li>A <code>state</code>: the current state value.</li>
<li>A <code>dispatch</code> function: a function that tells the respective reducer what to do next, and what data to act on.</li>
</ul>
<p>The image below explains each of the entities of the <code>useReducer</code> hook. If you want to learn about this hook in a greater depth, feel free to <a target="_blank" href="https://www.youtube.com/watch?v=PMyPyT8N4m8">check this out</a>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/03/image-27.png" alt="Image" width="600" height="400" loading="lazy">
<em>The Anatomy of the useReducer Hook</em></p>
<h2 id="heading-how-to-create-actions">How to Create Actions</h2>
<p>The reducer function is the heart of the useReducer hook. It performs all the necessary logic to keep your application state updated and valid. </p>
<p>But how would the reducer function be aware of its task? Who would tell the reducer function what to do and what kind of data to work on? Here comes <code>actions</code>, an object that contains all the details for the reducer.</p>
<p>We define actions with types that indicate the stages a state change will occur in the reducer function. The same action object may also carry the application data(at times we call it payload) to pass to the reducer function when a component performs a dispatch.</p>
<p>We will now get started by creating some actions. We will define the types here. As our reducer needs to manage the inventory state on a data fetch, data fetch success, and data fetch error, we'll be defining actions for each of those.</p>
<p>Create a directory called <code>actions/</code> under the <code>src/</code> directory. Now create a file called <code>index.js</code> under the <code>src/actions/</code> directory with the following content:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> FETCH_ACTIONS = {
  <span class="hljs-attr">PROGRESS</span>: <span class="hljs-string">'progress'</span>,
  <span class="hljs-attr">SUCCESS</span>: <span class="hljs-string">'success'</span>,
  <span class="hljs-attr">ERROR</span>: <span class="hljs-string">'error'</span>,
}

<span class="hljs-keyword">export</span> { FETCH_ACTIONS };
</code></pre>
<p>We have defined three actions, PROGRESS, SUCCESS, and ERROR. Next, let's create the reducer.</p>
<h2 id="heading-how-to-create-an-inventory-reducer">How to Create an Inventory Reducer</h2>
<p>We need a reducer where we will keep all the state change logic. The same reducer will be passed to the <code>useReducer</code> hook later to get the current state value and dispatch the function to the component.</p>
<p>Create a directory called <code>reducers/</code> under the <code>src/</code>. Now, create a file called <code>inventoryReducers.js</code> under the <code>src/reducers/</code> directory.</p>
<p>Our reducer will need the actions because it has to work on state changes based on the actions. So, let's import the actions into the <code>inventoryReducers.js</code> file:</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> { FETCH_ACTIONS } <span class="hljs-keyword">from</span> <span class="hljs-string">"../actions"</span>
</code></pre>
<p>You can define an initial state in the reducer file. The <code>useReducer</code> hook needs a reducer and an initial state to give us the current state value, remember? Let's define an initial state.</p>
<p>We need to show a list of inventory items after getting a successful API response. While we are fetching the list of items by making an API call, we need to manage a loading data state. </p>
<p>In case there is any problem in fetching data, we need to report the error using the error state. So we can create an initial state with all these values as object properties.</p>
<p>Now, create an initialState variable with the following state object value assigned to it:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> initialState = {
  <span class="hljs-attr">items</span>: [],
  <span class="hljs-attr">loading</span>: <span class="hljs-literal">false</span>,
  <span class="hljs-attr">error</span>: <span class="hljs-literal">null</span>,
}
</code></pre>
<p>Next, let's create the reducer function. Create a function called <code>inventoryReducer</code> with the following code snippet:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> inventoryReducer = <span class="hljs-function">(<span class="hljs-params">state, action</span>) =&gt;</span> {

  <span class="hljs-keyword">switch</span> (action.type) {
    <span class="hljs-keyword">case</span> FETCH_ACTIONS.PROGRESS: {
      <span class="hljs-keyword">return</span> {
        ...state,
        <span class="hljs-attr">loading</span>: <span class="hljs-literal">true</span>,
      }
    }

    <span class="hljs-keyword">case</span> FETCH_ACTIONS.SUCCESS: {
      <span class="hljs-keyword">return</span> {
        ...state,
        <span class="hljs-attr">loading</span>: <span class="hljs-literal">false</span>,
        <span class="hljs-attr">items</span>: action.data,
      }
    }

    <span class="hljs-keyword">case</span> FETCH_ACTIONS.ERROR: {
      <span class="hljs-keyword">return</span> {
        ...state,
        <span class="hljs-attr">loading</span>: <span class="hljs-literal">false</span>,
        <span class="hljs-attr">error</span>: action.error,
      }
    }

    <span class="hljs-attr">default</span>: {
      <span class="hljs-keyword">return</span> state;
    }      
  }

}
</code></pre>
<p>Let's understand the above code snippet. The <code>inventoryReducer</code> function takes two arguments, <code>state</code> and <code>action</code>. The reducer function works on the state based on the action type. For example,</p>
<ul>
<li>When it is a <code>PROGRESS</code> action, we want the <code>loading</code> value to be true.</li>
<li>For a <code>SUCCESS</code> action, we want to populate the <code>items</code> with the data received from the API response along with making the <code>loading</code> value as false.</li>
<li>For an <code>ERROR</code> action, we'll provide a value to the <code>error</code> property of the state.</li>
</ul>
<p>In any of the cases above, we do not mutate the state directly. Rather, we create a clone (a new reference of it using the <code>...</code> operator) of the state and then update its properties accordingly. Finally, we return the updated state for each of the actions. If the passed actions do not match any of the given types, we return back the state as it is.</p>
<p>Last, export the <code>inventoryReducer</code> function and the <code>initialState</code> object:</p>
<pre><code class="lang-js"><span class="hljs-keyword">export</span> {inventoryReducer, initialState};
</code></pre>
<p>Here is the complete code from the <code>inventoryReducers.js</code> file:</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> { FETCH_ACTIONS } <span class="hljs-keyword">from</span> <span class="hljs-string">"../actions"</span>

<span class="hljs-keyword">const</span> initialState = {
  <span class="hljs-attr">items</span>: [],
  <span class="hljs-attr">loading</span>: <span class="hljs-literal">false</span>,
  <span class="hljs-attr">error</span>: <span class="hljs-literal">null</span>,
}

<span class="hljs-keyword">const</span> inventoryReducer = <span class="hljs-function">(<span class="hljs-params">state, action</span>) =&gt;</span> {

  <span class="hljs-keyword">switch</span> (action.type) {
    <span class="hljs-keyword">case</span> FETCH_ACTIONS.PROGRESS: {
      <span class="hljs-keyword">return</span> {
        ...state,
        <span class="hljs-attr">loading</span>: <span class="hljs-literal">true</span>,
      }
    }

    <span class="hljs-keyword">case</span> FETCH_ACTIONS.SUCCESS: {
      <span class="hljs-keyword">return</span> {
        ...state,
        <span class="hljs-attr">loading</span>: <span class="hljs-literal">false</span>,
        <span class="hljs-attr">items</span>: action.data,
      }
    }

    <span class="hljs-keyword">case</span> FETCH_ACTIONS.ERROR: {
      <span class="hljs-keyword">return</span> {
        ...state,
        <span class="hljs-attr">loading</span>: <span class="hljs-literal">false</span>,
        <span class="hljs-attr">error</span>: action.error,
      }
    }

    <span class="hljs-attr">default</span>: {
      <span class="hljs-keyword">return</span> state;
    } 
  }

}

<span class="hljs-keyword">export</span> {inventoryReducer, initialState};
</code></pre>
<h2 id="heading-how-to-build-the-inventory-list-component">How to Build the Inventory List Component</h2>
<p>We will now create the inventory list component where we will use the reducer we created above.</p>
<p>Create a directory called <code>components/</code> under the <code>src/</code> directory. Now, create a file called <code>InventoryList.jsx</code> under the <code>stc/components/</code> directory.</p>
<p>First import the required things like:</p>
<ul>
<li>The <code>useReducer</code> hook where we will use the inventory reducer.</li>
<li>The <code>useEffect</code> hook to handle the async call with Axios.</li>
<li>The <code>inventory reducer</code> and the <code>initial state</code> we created a few minutes back.</li>
<li>The <code>actions</code>, as we need them to dispatch.</li>
<li>The <code>axios</code> for making async calls.</li>
</ul>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> { useReducer, useEffect } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;

<span class="hljs-keyword">import</span> { inventoryReducer, initialState } <span class="hljs-keyword">from</span> <span class="hljs-string">"../reducers/inventoryReducer"</span>;

<span class="hljs-keyword">import</span> { FETCH_ACTIONS } <span class="hljs-keyword">from</span> <span class="hljs-string">"../actions"</span>;

<span class="hljs-keyword">import</span> axios <span class="hljs-keyword">from</span> <span class="hljs-string">"axios"</span>;
</code></pre>
<p>Now, create a function to define the component:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> InventoryList = <span class="hljs-function">() =&gt;</span> {

  <span class="hljs-keyword">const</span> [state, dispatch] = useReducer(inventoryReducer, initialState);

  <span class="hljs-keyword">const</span> { items, loading, error} = state;

  <span class="hljs-keyword">return</span>(
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"flex flex-col m-8 w-2/5"</span>&gt;</span>

    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
};
</code></pre>
<p>Here,</p>
<ul>
<li>We have used the <code>useReducer</code> hook. We passed the <code>inventoryReducer</code> and the <code>initialState</code> to it as arguments to get the current <code>state</code> value and the <code>dispatch</code> function.</li>
<li>As we know the state object has the <code>items</code>, <code>loading</code>, and <code>error</code> as properties, we <code>destructure</code> them into our component. We will use them shortly.</li>
<li>The component returns an empty div that we will change as we proceed.</li>
</ul>
<p>Finally export the component as a default export like this:</p>
<pre><code class="lang-js"><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> InventoryList;
</code></pre>
<h2 id="heading-how-to-use-axios-to-fetch-data-and-dispatch-it-to-the-reducer">How to Use Axios to Fetch Data and Dispatch it to the Reducer</h2>
<p>It's data fetching time! Data fetching by making an asynchronous call is a side effect you need to handle in your component. Copy and paste the <code>useEffect</code> code block inside the <code>InventoryList</code> function. </p>
<pre><code class="lang-js"><span class="hljs-comment">// -- The code above as it is</span>

<span class="hljs-keyword">const</span> InventoryList = <span class="hljs-function">() =&gt;</span> {

  <span class="hljs-comment">// --- The code above as it is</span>


  useEffect(<span class="hljs-function">() =&gt;</span> {
    dispatch({<span class="hljs-attr">type</span>: FETCH_ACTIONS.PROGRESS});

    <span class="hljs-keyword">const</span> getItems = <span class="hljs-keyword">async</span> () =&gt; {
      <span class="hljs-keyword">try</span>{
        <span class="hljs-keyword">let</span> response = <span class="hljs-keyword">await</span> axios.get(<span class="hljs-string">"http://localhost:3000/edibles"</span>);
        <span class="hljs-keyword">if</span> (response.status === <span class="hljs-number">200</span>) {
          dispatch({<span class="hljs-attr">type</span>: FETCH_ACTIONS.SUCCESS, <span class="hljs-attr">data</span>: response.data});
        }
      } <span class="hljs-keyword">catch</span>(err){
        <span class="hljs-built_in">console</span>.error(err);
        dispatch({<span class="hljs-attr">type</span>: FETCH_ACTIONS.ERROR, <span class="hljs-attr">error</span>: err.message})
      }
    }

    getItems();

  }, []);

  <span class="hljs-comment">// --- The JSX return statement below as it is</span>
</code></pre>
<p>Let's understand the code flow:</p>
<ul>
<li>At the start of the <code>useEffect</code> callback, we dispatched a <code>PROGRESS</code> action. It invokes the reducer function with progress action type to turn the <code>loading</code> property value to true. We can use the loading property value in the JSX later to show a loading indicator.</li>
<li>Then we use Axios to make an asynchronous call using the API URL. On receiving the response, we check if it's a success, and in that case we dispatch a <code>SUCCESS</code> action along with the <code>items</code> data(remember, payload?) from response. This time the dispatcher will invoke the reducer with the success action to change the <code>items</code> and <code>loading</code> properties accordingly.</li>
<li>If there is an error, we dispatch an error action with the error message to update the state with the error information in the reducer.</li>
</ul>
<p>Each time we dispatch an action and update the state, we also get back the latest state value into our component. It's time to use the state value in the JSX to render the inventory item list.</p>
<h2 id="heading-lets-complete-the-jsx-part">Let's Complete the JSX Part</h2>
<p>The JSX part is fairly simple:</p>
<pre><code class="lang-js">
<span class="hljs-comment">// -- The code above as it is</span>

<span class="hljs-keyword">const</span> InventoryList = <span class="hljs-function">() =&gt;</span> {

  <span class="hljs-comment">// -- The code above as it is</span>

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"flex flex-col m-8 w-2/5"</span>&gt;</span>
      {
        loading ? (
          <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>
        ) : error ? (
          <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>{error}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
        ) : (
          <span class="hljs-tag">&lt;<span class="hljs-name">ul</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"flex flex-col"</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">h2</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"text-3xl my-4"</span>&gt;</span>Item List<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
            {
              items.map((item) =&gt; (
                <span class="hljs-tag">&lt;<span class="hljs-name">li</span>
                  <span class="hljs-attr">className</span>=<span class="hljs-string">"flex flex-col p-2 my-2 bg-gray-200 border rounded-md"</span> 
                  <span class="hljs-attr">key</span>=<span class="hljs-string">{item.id}</span>&gt;</span>
                  <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">className</span>=<span class="hljs-string">'my-2 text-xl'</span>&gt;</span>
                    <span class="hljs-tag">&lt;<span class="hljs-name">strong</span>&gt;</span>{item.name}<span class="hljs-tag">&lt;/<span class="hljs-name">strong</span>&gt;</span> {' '} {item.picture} of type <span class="hljs-tag">&lt;<span class="hljs-name">strong</span>&gt;</span>{item.type}<span class="hljs-tag">&lt;/<span class="hljs-name">strong</span>&gt;</span>
                    {' '} costs <span class="hljs-tag">&lt;<span class="hljs-name">strong</span>&gt;</span>{item.price}<span class="hljs-tag">&lt;/<span class="hljs-name">strong</span>&gt;</span> INR/KG.
                  <span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
                  <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">className</span>=<span class="hljs-string">'mb-2 text-lg'</span>&gt;</span>
                    Available in Stock: <span class="hljs-tag">&lt;<span class="hljs-name">strong</span>&gt;</span>{item.quantity}<span class="hljs-tag">&lt;/<span class="hljs-name">strong</span>&gt;</span>
                  <span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>

                <span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
              ))
            }

          <span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>
        )
      }

    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  )
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> InventoryList;
</code></pre>
<p>Here's what's going on in the code:</p>
<ul>
<li>We show a <code>loading...</code> message if the loading property of the state is true. </li>
<li>We show the error message in case there's an error.</li>
<li>In neither of the cases, we iterate through the inventory items using the map function. Each of the items in the <code>items</code> array has information like picture, name, price, and more. We show this information in a meaningful way.</li>
</ul>
<p>Here is the complete code of the <code>InventoryList</code> component:</p>
<pre><code class="lang-js">
<span class="hljs-keyword">import</span> { useReducer, useEffect } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
<span class="hljs-keyword">import</span> { inventoryReducer, initialState } <span class="hljs-keyword">from</span> <span class="hljs-string">"../reducers/inventoryReducer"</span>;
<span class="hljs-keyword">import</span> { FETCH_ACTIONS } <span class="hljs-keyword">from</span> <span class="hljs-string">"../actions"</span>;

<span class="hljs-keyword">import</span> axios <span class="hljs-keyword">from</span> <span class="hljs-string">"axios"</span>;

<span class="hljs-keyword">const</span> InventoryList = <span class="hljs-function">() =&gt;</span> {

  <span class="hljs-keyword">const</span> [state, dispatch] = useReducer(inventoryReducer, initialState);

  <span class="hljs-keyword">const</span> { items, loading, error} = state;

  <span class="hljs-built_in">console</span>.log(items, loading, error);

  useEffect(<span class="hljs-function">() =&gt;</span> {
    dispatch({<span class="hljs-attr">type</span>: FETCH_ACTIONS.PROGRESS});

    <span class="hljs-keyword">const</span> getItems = <span class="hljs-keyword">async</span> () =&gt; {
      <span class="hljs-keyword">try</span>{
        <span class="hljs-keyword">let</span> response = <span class="hljs-keyword">await</span> axios.get(<span class="hljs-string">"http://localhost:3000/edibles"</span>);
        <span class="hljs-keyword">if</span> (response.status === <span class="hljs-number">200</span>) {
          dispatch({<span class="hljs-attr">type</span>: FETCH_ACTIONS.SUCCESS, <span class="hljs-attr">data</span>: response.data});
        }
      } <span class="hljs-keyword">catch</span>(err){
        <span class="hljs-built_in">console</span>.error(err);
        dispatch({<span class="hljs-attr">type</span>: FETCH_ACTIONS.ERROR, <span class="hljs-attr">error</span>: err.message})
      }
    }

    getItems();

  }, []);


  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"flex flex-col m-8 w-2/5"</span>&gt;</span>
      {
        loading ? (
          <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>
        ) : error ? (
          <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>{error}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
        ) : (
          <span class="hljs-tag">&lt;<span class="hljs-name">ul</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"flex flex-col"</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">h2</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"text-3xl my-4"</span>&gt;</span>Item List<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
            {
              items.map((item) =&gt; (
                <span class="hljs-tag">&lt;<span class="hljs-name">li</span>
                  <span class="hljs-attr">className</span>=<span class="hljs-string">"flex flex-col p-2 my-2 bg-gray-200 border rounded-md"</span> 
                  <span class="hljs-attr">key</span>=<span class="hljs-string">{item.id}</span>&gt;</span>
                  <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">className</span>=<span class="hljs-string">'my-2 text-xl'</span>&gt;</span>
                    <span class="hljs-tag">&lt;<span class="hljs-name">strong</span>&gt;</span>{item.name}<span class="hljs-tag">&lt;/<span class="hljs-name">strong</span>&gt;</span> {' '} {item.picture} of type <span class="hljs-tag">&lt;<span class="hljs-name">strong</span>&gt;</span>{item.type}<span class="hljs-tag">&lt;/<span class="hljs-name">strong</span>&gt;</span>
                    {' '} costs <span class="hljs-tag">&lt;<span class="hljs-name">strong</span>&gt;</span>{item.price}<span class="hljs-tag">&lt;/<span class="hljs-name">strong</span>&gt;</span> INR/KG.
                  <span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
                  <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">className</span>=<span class="hljs-string">'mb-2 text-lg'</span>&gt;</span>
                    Available in Stock: <span class="hljs-tag">&lt;<span class="hljs-name">strong</span>&gt;</span>{item.quantity}<span class="hljs-tag">&lt;/<span class="hljs-name">strong</span>&gt;</span>
                  <span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>

                <span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
              ))
            }

          <span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>
        )
      }

    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  )
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> InventoryList
</code></pre>
<h2 id="heading-how-to-use-the-inventory-list-in-the-app-component">How to Use the Inventory List in the App Component</h2>
<p>Now we have to let the <code>App</code> component know about the <code>InventoryList</code> component so that we can render it. Open the <code>App.jsx</code> file and replace its content with the following code snippet:</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> InventoryList <span class="hljs-keyword">from</span> <span class="hljs-string">"./components/InventoryList"</span>

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">InventoryList</span> /&gt;</span>
    <span class="hljs-tag">&lt;/&gt;</span></span>
  )
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> App
</code></pre>
<p>That's it. Make sure your application server is running. Now, access the app on your browser using the following URL <a target="_blank" href="http://localhost:5173/"><code>http://localhost:5173/</code></a>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/03/image-28.png" alt="Image" width="600" height="400" loading="lazy">
<em>The Final Output - Inventory List</em></p>
<h2 id="heading-wrapping-up">Wrapping Up</h2>
<p>I hope you enjoyed building this project and learning more about React. <a target="_blank" href="https://github.com/atapas/youtube/tree/main/react/27-inventory-useReducer-jsonserver-axios">Here is the source code</a> on my GitHub. Please feel free to extend the project by adding features like:</p>
<ul>
<li>Adding an item to the inventory</li>
<li>Editing an item from the inventory</li>
<li>Deleting an item from the inventory</li>
</ul>
<p>Hint: You need to create actions for each of these and enhance the reducer function to write state update logic to support these features. I hope you give it a try and if you do so, let me know (my contacts are mentioned below). </p>
<p>That's all for now. I also publish meaningful posts on my <a target="_blank" href="https://blog.greenroots.info/">GreenRoots Blog</a>, and I think you'll find them helpful, too.</p>
<p>Let's connect.</p>
<ul>
<li>I am an educator on my YouTube channel, <code>tapaScript</code>. Please <a target="_blank" href="https://www.youtube.com/tapasadhikary?sub_confirmation=1">SUBSCRIBE</a> to the channel if you want to learn JavaScript, ReactJS, Next.js, Node.js, Git, and all about Web Development fundamentally.</li>
<li><a target="_blank" href="https://twitter.com/tapasadhikary">Follow me on X (Twitter</a>) or <a target="_blank" href="https://www.linkedin.com/in/tapasadhikary/">LinkedIn</a> if you don't want to miss the daily dose of Web Development and Programming Tips.</li>
<li>Find all my public speaking talks <a target="_blank" href="https://www.tapasadhikary.com/talks">here</a>.</li>
<li>Check out and follow my Open Source work on <a target="_blank" href="https://github.com/atapas">GitHub</a>.</li>
</ul>
<p>See you soon with my next article. Until then, please take care of yourself, and stay happy.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Work with useMemo in React – with Code Examples ]]>
                </title>
                <description>
                    <![CDATA[ useMemo is a valuable tool in the React framework, designed to optimize performance by memoizing expensive computations.  With useMemo, React can store the result of a function call and reuse it when the dependencies of that function haven't changed,... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-work-with-usememo-in-react/</link>
                <guid isPermaLink="false">66c4c3f1356b00550fa89b5a</guid>
                
                    <category>
                        <![CDATA[ hooks ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Joan Ayebola ]]>
                </dc:creator>
                <pubDate>Wed, 07 Feb 2024 18:13:41 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/02/Ivory-and-Blue-Lavender-Aesthetic-Photo-Collage-Presentation--6-.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p><code>useMemo</code> is a valuable tool in the React framework, designed to optimize performance by memoizing expensive computations. </p>
<p>With <code>useMemo</code>, React can store the result of a function call and reuse it when the dependencies of that function haven't changed, rather than recalculating the value on every render. </p>
<p><code>useMemo</code> stands out as a powerful tool for optimizing performance without sacrificing code readability or maintainability. But it's often overlooked or misunderstood by beginners. </p>
<p>In this comprehensive guide, we'll discuss what <code>useMemo</code> is, how it works, and why it's an essential tool for every React developer.</p>
<h3 id="heading-table-of-contents">Table of Contents</h3>
<ol>
<li><a class="post-section-overview" href="#heading-what-is-usememo">What is useMemo?</a></li>
<li><a class="post-section-overview" href="#heading-how-does-usememo-work">How does useMemo Work?</a></li>
<li><a class="post-section-overview" href="#heading-when-to-use-usememo">When to Use useMemo?</a><br>– <a class="post-section-overview" href="#heading-data-formatting">Data Formatting</a><br>– <a class="post-section-overview" href="#heading-filtering-data">Filtering Data</a><br>– <a class="post-section-overview" href="#heading-sorting-data">Sorting Data</a><br>– <a class="post-section-overview" href="#memorizing-callback-functions-">Memoizing Callback Functions</a><br>– <a class="post-section-overview" href="#heading-expensive-calculations">Expensive Calculations</a></li>
<li><a class="post-section-overview" href="#heading-benefits-of-usememo">Benefits of useMemo</a></li>
<li><a class="post-section-overview" href="#syntax-and-usage-of-the-usememo-hook-">Syntax and Usage of the useMemo Hook</a><br>– <a class="post-section-overview" href="#heading-avoiding-unnecessary-recalculations">Avoiding Unnecessary Recalculations</a><br>– <a class="post-section-overview" href="#heading-optimizing-rendering-performance">Optimizing Rendering Performance</a><br>– <a class="post-section-overview" href="#heading-efficiently-managing-derived-data">Efficiently Managing Derived Data</a><br>– <a class="post-section-overview" href="#heading-enhancing-user-experience">Enhancing User Experience</a></li>
<li><a class="post-section-overview" href="#heading-how-does-usememo-differ-from-other-hooks-like-usestate-and-useeffect">How does useMemo differ from other hooks like useState and useEffect?</a><br>– <a class="post-section-overview" href="#heading-usestate">useState</a><br>– <a class="post-section-overview" href="#heading-useeffect">useEffect</a><br>– <a class="post-section-overview" href="#heading-usememo">useMemo</a></li>
<li><a class="post-section-overview" href="#how-to-memorize-expensive-computations-using-usememo">How to Memoize Expensive Computations Using useMemo</a><br>– <a class="post-section-overview" href="#heading-identify-the-expensive-computation">Identify the Expensive Computation</a><br>– <a class="post-section-overview" href="#heading-wrap-the-computation-with-usememo">Wrap the Computation with useMemo</a><br>– <a class="post-section-overview" href="#heading-specify-dependencies">Specify Dependencies</a></li>
<li><a class="post-section-overview" href="#heading-how-to-optimize-complex-calculations-within-render-props-or-higher-order-components">How to Optimize Complex Calculations within Render Props or Higher-Order Components</a></li>
<li><a class="post-section-overview" href="#heading-how-to-use-usememo-with-custom-hooks">How to Use useMemo with Custom Hooks</a></li>
<li><a class="post-section-overview" href="#heading-tips-for-using-usememo-effectively">Tips for Using useMemo Effectively</a><br>– <a class="post-section-overview" href="#identify-expensive-computations-">Identify expensive computations</a><br>– <a class="post-section-overview" href="#choose-the-right-dependencies-">Choose the right dependencies</a><br>– <a class="post-section-overview" href="#avoid-unnecessary-memorization-">Avoid unnecessary memorization</a><br>– <a class="post-section-overview" href="#measure-performance-">Measure performance</a></li>
<li><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></li>
</ol>
<h2 id="heading-what-is-usememo">What is useMemo?</h2>
<p><code>useMemo</code> is a handy tool in React that helps make your apps faster. Imagine you have a function that does some heavy lifting, like calculating a complex math problem or formatting data. Normally, React recalculates this function every time your component renders, even if the inputs are the same. That can slow things down.</p>
<p>But with <code>useMemo</code>, React remembers the result of that function as long as its inputs stay the same. So, if your inputs don't change, React just grabs the stored result instead of recalculating it every time. This saves time and makes your app snappier. </p>
<p>In simple terms, <code>useMemo</code> is like having a smart assistant who remembers the answers to math problems, so you don't have to solve them again and again.</p>
<h2 id="heading-how-does-usememo-work">How Does useMemo Work?</h2>
<p>To understand how <code>useMemo</code> works, let's consider a scenario where you have a component that renders a list of items, and you need to perform some heavy computation to derive the list. </p>
<p>Without memoization, this heavy computation would be executed on every render, even if the inputs remain unchanged.</p>
<p>Here's a basic example without <code>useMemo</code>:</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-keyword">const</span> ListComponent = <span class="hljs-function">(<span class="hljs-params">{ items }</span>) =&gt;</span> {
  <span class="hljs-keyword">const</span> processedItems = processItems(items); <span class="hljs-comment">// Expensive computation</span>

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span>
      {processedItems.map(item =&gt; (
        <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">key</span>=<span class="hljs-string">{item.id}</span>&gt;</span>{item.name}<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
      ))}
    <span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span></span>
  );
};

<span class="hljs-keyword">const</span> processItems = <span class="hljs-function">(<span class="hljs-params">items</span>) =&gt;</span> {
  <span class="hljs-comment">// Expensive computation</span>
  <span class="hljs-comment">// Imagine some heavy processing here</span>
  <span class="hljs-keyword">return</span> items.map(<span class="hljs-function"><span class="hljs-params">item</span> =&gt;</span> ({ <span class="hljs-attr">id</span>: item.id, <span class="hljs-attr">name</span>: item.name.toUpperCase() }));
};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> ListComponent;
</code></pre>
<p>In this example, <code>processItems</code> function gets called on every render, even if the <code>items</code> prop remains the same. </p>
<p>To optimize this, we can use <code>useMemo</code>:</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> React, { useMemo } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-keyword">const</span> ListComponent = <span class="hljs-function">(<span class="hljs-params">{ items }</span>) =&gt;</span> {
  <span class="hljs-keyword">const</span> processedItems = useMemo(<span class="hljs-function">() =&gt;</span> processItems(items), [items]);

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span>
      {processedItems.map(item =&gt; (
        <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">key</span>=<span class="hljs-string">{item.id}</span>&gt;</span>{item.name}<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
      ))}
    <span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span></span>
  );
};

<span class="hljs-keyword">const</span> processItems = <span class="hljs-function">(<span class="hljs-params">items</span>) =&gt;</span> {
  <span class="hljs-comment">// Expensive computation</span>
  <span class="hljs-comment">// Imagine some heavy processing here</span>
  <span class="hljs-keyword">return</span> items.map(<span class="hljs-function"><span class="hljs-params">item</span> =&gt;</span> ({ <span class="hljs-attr">id</span>: item.id, <span class="hljs-attr">name</span>: item.name.toUpperCase() }));
};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> ListComponent;
</code></pre>
<p>By wrapping the <code>processItems</code> call inside <code>useMemo</code>, React will only recompute the memoized value when the <code>items</code> prop changes. This optimization can significantly improve the performance of your application, especially when dealing with large datasets or complex computations.</p>
<h2 id="heading-when-to-use-usememo">When to Use useMemo</h2>
<p>You should use <code>useMemo</code> in scenarios where you have expensive computations or data transformations within a functional component that are being unnecessarily recalculated on every render. </p>
<p>Here are some practical examples illustrating basic usage scenarios for <code>useMemo</code>:</p>
<h3 id="heading-data-formatting">Data Formatting:</h3>
<pre><code class="lang-jsx"><span class="hljs-keyword">const</span> formattedData = useMemo(<span class="hljs-function">() =&gt;</span> formatData(rawData), [rawData]);
</code></pre>
<ul>
<li>Use <code>useMemo</code> to format raw data into a display-friendly format.</li>
<li>Recompute <code>formattedData</code> only when <code>rawData</code> changes, optimizing performance.</li>
</ul>
<h3 id="heading-filtering-data">Filtering Data:</h3>
<pre><code class="lang-jsx"><span class="hljs-keyword">const</span> filteredData = useMemo(<span class="hljs-function">() =&gt;</span> filterData(rawData, filterCriteria), [rawData, filterCriteria]);
</code></pre>
<ul>
<li>Use <code>useMemo</code> to filter a list of data based on certain criteria.</li>
<li>Ensure <code>filteredData</code> is recalculated only when <code>rawData</code> or <code>filterCriteria</code> change.</li>
</ul>
<h3 id="heading-sorting-data">Sorting Data:</h3>
<pre><code class="lang-jsx"><span class="hljs-keyword">const</span> sortedData = useMemo(<span class="hljs-function">() =&gt;</span> sortData(rawData, sortKey), [rawData, sortKey]);
</code></pre>
<ul>
<li>Use <code>useMemo</code> to sort a list of data based on a specific key.</li>
<li>Re-sort <code>sortedData</code> only when <code>rawData</code> or <code>sortKey</code> change.</li>
</ul>
<h3 id="heading-memoizing-callback-functions">Memoizing Callback Functions:</h3>
<pre><code class="lang-jsx"><span class="hljs-keyword">const</span> handleClick = useMemo(<span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">return</span> <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-comment">// Handle click event</span>
  };
}, []);
</code></pre>
<ul>
<li>Use <code>useMemo</code> to memoize callback functions to prevent unnecessary function recreations on every render.</li>
<li>Pass an empty dependency array (<code>[]</code>) to ensure the callback function is only created once during the component's lifecycle.</li>
</ul>
<h3 id="heading-expensive-calculations">Expensive Calculations:</h3>
<pre><code class="lang-jsx"><span class="hljs-keyword">const</span> result = useMemo(<span class="hljs-function">() =&gt;</span> {
  <span class="hljs-comment">// Perform expensive calculation</span>
  <span class="hljs-keyword">return</span> performCalculation(input1, input2);
}, [input1, input2]);
</code></pre>
<ul>
<li>Use <code>useMemo</code> to memoize the result of an expensive calculation.</li>
<li>Recalculate <code>result</code> only when <code>input1</code> or <code>input2</code> change.</li>
</ul>
<p>In each of these examples, <code>useMemo</code> ensures that the expensive computation or transformation is only performed when necessary, reducing unnecessary recalculations and optimizing the performance of your functional components.</p>
<h2 id="heading-benefits-of-usememo">Benefits of useMemo</h2>
<p>Utilizing the <code>useMemo</code> hook in React applications offers numerous benefits for performance optimization. </p>
<h3 id="heading-avoiding-unnecessary-recalculations">Avoiding Unnecessary Recalculations:</h3>
<p>In React, components re-render whenever their state or props change. If a component performs expensive computations or calculations within its rendering logic, these computations can be re-executed on every render, even if the inputs haven't changed.</p>
<p>By using <code>useMemo</code>, you can memoize these computations. React will only recalculate the memoized value when the dependencies (inputs) change. This helps avoid unnecessary recalculations, improving the performance of your components.</p>
<h3 id="heading-optimizing-rendering-performance">Optimizing Rendering Performance:</h3>
<p>React components can become slow to render if they perform heavy computations or transformations during each render cycle. This is particularly problematic in large-scale applications or components that render frequently.</p>
<p><code>useMemo</code> allows you to memoize the results of these computations, ensuring that they are only performed when necessary. This can lead to significant improvements in rendering performance by reducing the computational overhead of your components.</p>
<h3 id="heading-efficiently-managing-derived-data">Efficiently Managing Derived Data:</h3>
<p>In many React applications, derived data is computed from the state or props of components. For example, computed properties, filtered lists, or formatted data are often derived from raw data sources.</p>
<p>Memoizing derived data with <code>useMemo</code> ensures that these computations are performed efficiently and only when needed. This can prevent unnecessary re-renders and optimize the overall performance of your application.</p>
<h3 id="heading-enhancing-user-experience">Enhancing User Experience:</h3>
<p>Performance optimization is crucial for delivering a smooth and responsive user experience. Slow or unresponsive components can lead to a poor user experience and frustrate users.</p>
<p>By leveraging <code>useMemo</code> to optimize the performance of your components, you can ensure that your application remains fast and responsive, improving user satisfaction and engagement.</p>
<p><code>useMemo</code> is essential for performance optimization in React applications because it allows you to avoid unnecessary recalculations, optimize rendering performance, efficiently manage derived data, and enhance the overall user experience. </p>
<p>By memoizing expensive computations with <code>useMemo</code>, you can create fast, responsive, and efficient React components that deliver a seamless user experience.</p>
<h2 id="heading-syntax-and-usage-of-the-usememo-hook">Syntax and Usage of the useMemo Hook</h2>
<p>The <code>useMemo</code> hook in React is used to memoize expensive computations. Its syntax is straightforward, and it takes two arguments: a function representing the computation to be memoized, and an array of dependencies. </p>
<p>Here's the syntax and usage of the <code>useMemo</code> hook:</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> React, { useMemo } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-keyword">const</span> MyComponent = <span class="hljs-function">(<span class="hljs-params">{ data }</span>) =&gt;</span> {
  <span class="hljs-comment">// Memoize the result of the expensive computation</span>
  <span class="hljs-keyword">const</span> memoizedValue = useMemo(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-comment">// Perform some expensive computation using the data</span>
    <span class="hljs-keyword">return</span> processData(data);
  }, [data]); <span class="hljs-comment">// Dependency array: recompute if 'data' changes</span>

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      {/* Render the memoized value */}
      <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>{memoizedValue}<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>
  );
};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> MyComponent;
</code></pre>
<p>In this example:</p>
<ol>
<li>We import <code>useMemo</code> from the React library.</li>
<li>Inside the functional component <code>MyComponent</code>, we declare a constant <code>memoizedValue</code> using the <code>useMemo</code> hook.</li>
<li>The first argument of <code>useMemo</code> is a function that performs the expensive computation. In this case, we call <code>processData</code> function and pass <code>data</code> as a parameter.</li>
<li>The second argument of <code>useMemo</code> is an array of dependencies. React will only recompute the memoized value if any of these dependencies change. Here, we specify <code>[data]</code> as the dependency array, indicating that <code>memoizedValue</code> should be recalculated whenever the <code>data</code> prop changes.</li>
<li>Finally, we render the <code>memoizedValue</code> inside the component's JSX.</li>
</ol>
<p>By using <code>useMemo</code>, we ensure that the expensive computation inside the function is only executed when necessary, optimizing the performance of our component.</p>
<h2 id="heading-how-does-usememo-differ-from-other-hooks-like-usestate-and-useeffect">How Does useMemo Differ from Other Hooks Like useState and useEffect?</h2>
<p><code>useMemo</code> differs from other hooks like <code>useState</code> and <code>useEffect</code> in its purpose and how it affects component behavior:</p>
<h3 id="heading-usestate">useState:</h3>
<ul>
<li><code>useState</code> is used for managing state within functional components.</li>
<li>It allows you to create and update state variables, triggering re-renders when their values change.</li>
<li>State variables managed by <code>useState</code> are typically used for storing data that can change over time, such as form inputs, toggles, or counters.</li>
</ul>
<h3 id="heading-useeffect">useEffect:</h3>
<ul>
<li><code>useEffect</code> is used for handling side effects within functional components.</li>
<li>It runs after every render and enables you to perform tasks like data fetching, subscriptions, or DOM manipulation.</li>
<li><code>useEffect</code> allows you to separate side effects from the main component logic, keeping your components clean and organized.</li>
</ul>
<h3 id="heading-usememo">useMemo:</h3>
<ul>
<li><code>useMemo</code> is used for memoizing expensive computations within functional components.</li>
<li>It caches the result of a function and returns the cached result when the inputs to the function remain unchanged.</li>
<li>Unlike <code>useState</code> and <code>useEffect</code>, which manage state and side effects respectively, <code>useMemo</code> focuses solely on optimizing performance by avoiding unnecessary recalculations.</li>
</ul>
<p>While <code>useState</code> and <code>useEffect</code> are used for managing state and handling side effects, respectively, <code>useMemo</code> is specifically designed for performance optimization by memoizing computations. Each hook serves a distinct purpose in React development, but they can be used together to build efficient and maintainable components.</p>
<h2 id="heading-how-to-memoize-expensive-computations-using-usememo">How to Memoize Expensive Computations using useMemo</h2>
<p>To memoize expensive computations using <code>useMemo</code>, follow these steps:</p>
<h3 id="heading-identify-the-expensive-computation">Identify the Expensive Computation:</h3>
<p>Determine which computations in your component are expensive and would benefit from memoization. These could include complex calculations, data transformations, or function calls that consume significant resources.</p>
<h3 id="heading-wrap-the-computation-with-usememo">Wrap the Computation with useMemo:</h3>
<p>Use the <code>useMemo</code> hook to memoize the result of the computation. The first argument to <code>useMemo</code> is a function that performs the computation, and the second argument is an array of dependencies.</p>
<h3 id="heading-specify-dependencies">Specify Dependencies:</h3>
<p>Provide an array of dependencies to <code>useMemo</code> to indicate when the memoized value should be recalculated. If any of the dependencies change, <code>useMemo</code> will recompute the memoized value.</p>
<p>Here's an example of how to memoize an expensive computation using <code>useMemo</code>:</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> React, { useMemo } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-keyword">const</span> MyComponent = <span class="hljs-function">(<span class="hljs-params">{ data }</span>) =&gt;</span> {
  <span class="hljs-comment">// Memoize the result of the expensive computation</span>
  <span class="hljs-keyword">const</span> memoizedValue = useMemo(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-comment">// Perform the expensive computation here</span>
    <span class="hljs-keyword">return</span> processData(data);
  }, [data]); <span class="hljs-comment">// 'data' is a dependency</span>

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      {/* Render the memoized value */}
      <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>{memoizedValue}<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>
  );
};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> MyComponent;
</code></pre>
<p>In this example:</p>
<ul>
<li>We use <code>useMemo</code> to memoize the result of the <code>processData</code> function, which performs the expensive computation.</li>
<li>The <code>data</code> prop is specified as a dependency in the dependency array <code>[data]</code>. This means that <code>memoizedValue</code> will be recalculated whenever the <code>data</code> prop changes.</li>
<li>The memoized value (<code>memoizedValue</code>) is then rendered inside the component's JSX.</li>
</ul>
<p>By memoizing the expensive computation with <code>useMemo</code>, we ensure that it is only recomputed when necessary, optimizing the performance of our component.</p>
<h2 id="heading-how-to-optimize-complex-calculations-within-render-props-or-higher-order-components">How to Optimize Complex Calculations within Render Props or Higher-order Components</h2>
<p><code>useMemo</code> can also be effectively utilized within render props or higher-order components (HOCs) to optimize complex calculations. Consider the following HOC example:</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> React, { useMemo } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-keyword">const</span> withDataFetching = <span class="hljs-function">(<span class="hljs-params">WrappedComponent</span>) =&gt;</span> {
  <span class="hljs-keyword">return</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">WithDataFetching</span>(<span class="hljs-params">{ data }</span>) </span>{
    <span class="hljs-comment">// Memoize the processedData calculation</span>
    <span class="hljs-keyword">const</span> processedData = useMemo(<span class="hljs-function">() =&gt;</span> processData(data), [data]);

    <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">WrappedComponent</span> <span class="hljs-attr">processedData</span>=<span class="hljs-string">{processedData}</span> /&gt;</span></span>;
  };
};

<span class="hljs-keyword">const</span> DisplayData = <span class="hljs-function">(<span class="hljs-params">{ processedData }</span>) =&gt;</span> {
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      {processedData.map(item =&gt; (
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">key</span>=<span class="hljs-string">{item.id}</span>&gt;</span>{item.name}<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
      ))}
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
};

<span class="hljs-keyword">const</span> processData = <span class="hljs-function">(<span class="hljs-params">data</span>) =&gt;</span> {
  <span class="hljs-comment">// Expensive computation</span>
  <span class="hljs-comment">// Imagine some heavy processing here</span>
  <span class="hljs-keyword">return</span> data.map(<span class="hljs-function"><span class="hljs-params">item</span> =&gt;</span> ({ <span class="hljs-attr">id</span>: item.id, <span class="hljs-attr">name</span>: item.name.toUpperCase() }));
};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> withDataFetching(DisplayData);
</code></pre>
<p>In this example, <code>processedData</code> is memoized within the <code>withDataFetching</code> HOC using <code>useMemo</code>. This optimization ensures that the heavy computation in <code>processData</code> is only performed when the <code>data</code> prop changes, improving the overall performance of the component.</p>
<h2 id="heading-how-to-use-usememo-with-custom-hooks">How to Use useMemo with Custom Hooks</h2>
<p>Another powerful use case for <code>useMemo</code> is within custom hooks to memoize values across components. Let's create a custom hook that fetches data from an API and memoizes the result:</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> { useState, useEffect, useMemo } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-keyword">const</span> useDataFetching = <span class="hljs-function">(<span class="hljs-params">url</span>) =&gt;</span> {
  <span class="hljs-keyword">const</span> [data, setData] = useState(<span class="hljs-literal">null</span>);

  useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">const</span> fetchData = <span class="hljs-keyword">async</span> () =&gt; {
      <span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> fetch(url);
      <span class="hljs-keyword">const</span> result = <span class="hljs-keyword">await</span> response.json();
      setData(result);
    };

    fetchData();
  }, [url]);

  <span class="hljs-comment">// Memoize the data value</span>
  <span class="hljs-keyword">const</span> memoizedData = useMemo(<span class="hljs-function">() =&gt;</span> data, [data]);

  <span class="hljs-keyword">return</span> memoizedData;
};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> useDataFetching;
</code></pre>
<p>Now, whenever we use <code>useDataFetching</code> hook in a component, the <code>data</code> value will be memoized using <code>useMemo</code>. This ensures that the fetched data is only recalculated when the URL changes, preventing unnecessary API calls and improving performance across components.</p>
<h2 id="heading-tips-for-using-usememo-effectively">Tips for Using useMemo Effectively</h2>
<p>Here are some tips for using <code>useMemo</code> effectively:</p>
<ol>
<li>Identify expensive computations: Identify the parts of your application that involve heavy computations or calculations.</li>
<li>Choose the right dependencies: Ensure that you include all the necessary dependencies in the dependency array. Missing dependencies could lead to unexpected behavior.</li>
<li>Avoid unnecessary memoization: Avoid memorizing values that don't need to be memoized, as it can add unnecessary complexity to your code.</li>
<li>Measure performance: Use performance monitoring tools to measure the impact of <code>useMemo</code> on your application's performance and adjust accordingly.</li>
</ol>
<h2 id="heading-conclusion">Conclusion</h2>
<p><code>useMemo</code> is a powerful tool for optimizing the performance of your React applications by memoizing the result of expensive computations. </p>
<p>By using <code>useMemo</code> effectively, you can prevent unnecessary re-renders and improve the overall responsiveness of your application. </p>
<p>So, don't ignore <code>useMemo</code> just because it seems intimidating. Embrace it as a valuable tool in your React development journey, and harness its potential to create faster and more efficient web applications.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Use the SWR Library for Better Data Fetching in React ]]>
                </title>
                <description>
                    <![CDATA[ React is un-opinionated about how you fetch and manage the remote data in your application. You may think of using the useEffect hook for simple fetching operations, but it will not help you with caching, request deduplication, always serving real-ti... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/swr-library-for-data-fetching-in-react/</link>
                <guid isPermaLink="false">66ba12309065919bb4e84cba</guid>
                
                    <category>
                        <![CDATA[ hooks ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Furkan Emin Can ]]>
                </dc:creator>
                <pubDate>Tue, 05 Dec 2023 21:59:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/12/Cover.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>React is un-opinionated about how you fetch and manage the remote data in your application.</p>
<p>You may think of using the <code>useEffect</code> hook for simple fetching operations, but it will not help you with caching, request deduplication, always serving real-time data, and so on.</p>
<p>Things will get more complicated when you try to implement them by yourself. But fortunately, the SWR library helps us solve some common problems and it also simplifies development.</p>
<h2 id="heading-what-is-the-swr-library">What is the SWR Library?</h2>
<p>According to the <a target="_blank" href="https://swr.vercel.app">SWR documentation</a>:</p>
<blockquote>
<p>The name “SWR” is derived from <code>stale-while-revalidate</code>, a HTTP cache invalidation strategy popularized by <a target="_blank" href="https://tools.ietf.org/html/rfc5861">HTTP RFC 5861</a>.   </p>
<p>SWR is a strategy to first return the data from cache (stale), then send the fetch request (revalidate), and finally come with the up-to-date data.</p>
</blockquote>
<p>With the help of this strategy, you can make sure to always display up-to-date data to your users.</p>
<p>So, SWR is a library built upon the <code>stale-while-revalidate</code> strategy, and it provides React hooks for data fetching.</p>
<p>Before moving on to the details, let's look at the two most important concepts of SWR.</p>
<h3 id="heading-caching">Caching</h3>
<p>A cache stores data for a specified amount of time and serves this data to users who request it within that period of time.</p>
<p>The time can be a certain period like <code>5000ms</code> or can be an event like re-connecting to the Internet.</p>
<p>SWR automatically caches the fetched data, helping to quickly serve the data without making redundant network requests.</p>
<h3 id="heading-revalidation">Revalidation</h3>
<p>When the valid time is exceeded, the data becomes stale. When a user requests this data you should revalidate it before serving it.</p>
<p>If the data is stale, SWR revalidates it (re-fetches from the server) to keep it fresh.</p>
<p>By default, SWR automatically revalidates the data (it assumes that the data is stale) in three cases:</p>
<ol>
<li>Every time the component is mounted, even if there is data in the cache, it revalidates.</li>
<li>It revalidates when the window gets focused.</li>
<li>It revalidates when the browser regains its network connection.</li>
</ol>
<h2 id="heading-how-to-use-the-useswr-hook">How to Use the <code>useSWR</code> Hook</h2>
<p>The <code>useSWR</code> hook is the main hook of the library. In your projects, you'll almost always use this hook.</p>
<p>It accepts three parameters: <code>key</code>, <code>fetcher</code>, and <code>options</code>.</p>
<ul>
<li><code>key</code> is a unique string for the request like an id.</li>
<li><code>fetcher</code> is an async function that accepts the <code>key</code> and returns the <code>data</code>. SWR automatically passes the <code>key</code> to the <code>fetcher</code> function when loading the data.</li>
<li><code>options</code> is an object of options available for the hook. For example, you can specify the cache time in the <code>options</code> object.</li>
</ul>
<p>And it returns an object with <code>data</code>, <code>error</code>, <code>isValidating</code>, <code>isLoading</code>, and <code>mutate</code> properties.</p>
<ul>
<li><code>data</code> is the variable returned from the <code>fetcher</code> function. During the first request, it will be <code>undefined</code>.</li>
<li><code>error</code> is the error thrown by the <code>fetcher</code> function. If there is no error, it will be <code>undefined</code>.</li>
<li><code>isLoading</code> is a boolean that indicates the <strong>first</strong> request's status. It is <code>true</code> during the first request, and it will always be <code>false</code> thereafter.</li>
<li><code>isValidating</code> is also a boolean that indicates the request's status. It is <code>true</code> during each request including the first one.</li>
<li><code>mutate</code> is a function for manually triggering a revalidation.</li>
</ul>
<h2 id="heading-how-i-used-swr-in-my-project">How I Used SWR in My Project</h2>
<p>The best thing about SWR is how easy it is to use. I tried out it in my first project for the <a target="_blank" href="https://www.freecodecamp.org/learn/front-end-development-libraries">Front End Libraries Certification</a> of freeCodeCamp and liked it very much.</p>
<p>I used TypeScript for the project, but will give you examples with JavaScript. So, don't worry if you don't know TypeScript – I highly recommend giving it a try if you haven't yet.</p>
<p>Also, if you are interested, you can find the project's code in its <a target="_blank" href="https://github.com/femincan/quote-factory">GitHub repository</a>.</p>
<h3 id="heading-how-to-add-the-swr-dependency-to-the-project">How to Add the <code>swr</code> Dependency to the Project</h3>
<p>To be able to use the library, you can install it via <code>npm</code>, <code>pnpm</code>, or <code>yarn</code>. I prefer using <code>pnpm</code> as the package manager for my project.</p>
<pre><code class="lang-bash">$ npm i swr
<span class="hljs-comment"># or</span>
$ pnpm add swr
<span class="hljs-comment"># or</span>
$ yarn add swr
</code></pre>
<h3 id="heading-create-the-fetcher-function">Create the <code>fetcher</code> Function</h3>
<p>The goal of this function is to fetch the data by URL and return it. I will use the function with SWR.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> fetcher = <span class="hljs-keyword">async</span> (url) =&gt; {
  <span class="hljs-keyword">const</span> { data } = <span class="hljs-keyword">await</span> axios.get(url);

  <span class="hljs-keyword">return</span> data;
};
</code></pre>
<p>The <code>fetcher</code> function:</p>
<ul>
<li>accepts a <code>url</code> parameter,</li>
<li>fetches the data with the <code>get</code> method of Axios,</li>
<li>returns the <code>data</code> returned from the request.</li>
</ul>
<h3 id="heading-create-a-hook-that-fetches-a-random-quote">Create a Hook That Fetches a Random Quote</h3>
<p>Based on the <a target="_blank" href="https://swr.vercel.app/docs/getting-started#make-it-reusable">SWR documentation</a>, I created a hook called <code>useRandomQuote</code>. This hook is a wrapper for the <code>useSWR</code> hook. Thus, I can use the same data wherever needed.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> useSWR <span class="hljs-keyword">from</span> <span class="hljs-string">'swr/immutable'</span>;

<span class="hljs-keyword">const</span> useRandomQuote = <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">const</span> { data, ...restSWR } = useSWR(
    <span class="hljs-string">'https://api.quotable.io/quotes/random'</span>,
    fetcher
  );

  <span class="hljs-keyword">return</span> {
    ...restSWR,
    <span class="hljs-attr">quote</span>: data?.[<span class="hljs-number">0</span>],
  };
};

<span class="hljs-keyword">export</span> { useRandomQuote };
</code></pre>
<p>The hook fetches the data with <code>useSWR</code> and returns an object that contains the variables destructured from the <code>useSWR</code> hook and the <code>quote</code> property which is the only element in the returned array. I used the Quotable API for a random quote, and the API returns an array with one element which is the random quote.</p>
<p>If you noticed, I imported the <code>useSWR</code> hook from <code>swr/immutable</code> in the code snippet. It is auto-revalidation disabled version of the hook. I prefer to use it because I want to revalidate the data manually with the <code>mutate</code> function.</p>
<h3 id="heading-how-to-revalidate-the-data-manually">How to Revalidate the Data Manually</h3>
<p>If you want to manually revalidate the data, you can use the <code>mutate</code> function returned from the <code>useSWR</code> hook.</p>
<p>When the mutate function is called, SWR revalidates the data. During this process, the <code>data</code> variable remains the same (will not be undefined), and the <code>isValidating</code> variable becomes true.</p>
<p>The following diagram from the <a target="_blank" href="https://swr.vercel.app/docs/advanced/understanding#fetch-and-revalidate">SWR documentation</a> visualizes the revalidation process:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/fetch-and-revalidate-pattern.png" alt="A diagram for the &quot;Fetch and Revalidate&quot; pattern in SWR" width="600" height="400" loading="lazy">
<em>A diagram for the "Fetch and Revalidate" pattern in SWR</em></p>
<p>In my project, I have a <code>QuoteCard</code> component that displays the current quote. This component has a <code>New Quote</code> button that triggers retrieving a new random quote.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> QuoteCard = <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">const</span> { <span class="hljs-comment">/* ... */</span>, mutate } = useRandomQuote();

  <span class="hljs-keyword">return</span> (
    {<span class="hljs-comment">/* ... */</span>}
    &lt;button
      <span class="hljs-comment">// ...</span>
      onClick={<span class="hljs-function">() =&gt;</span> mutate()}
    &gt;
      New Quote
    &lt;/button&gt;
    {<span class="hljs-comment">/* ... */</span>}
  )
}
</code></pre>
<p>In the code above, I used the <code>mutate</code> function in the <code>onClick</code> handler of the <code>New Quote</code> button.</p>
<h3 id="heading-how-to-handle-concurrent-requests">How to Handle Concurrent Requests</h3>
<p>If the user initiates a new request alongside the ongoing one, this results in multiple concurrent requests. Each request waits for the previous one to complete before starting the process, resulting in unnecessary network usage and waiting time.</p>
<p>I faced the same issue in my project. When the user clicks the <code>New Quote</code> button while a request is still loading, the application triggers a new request alongside the existing one.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/illustration.gif" alt="Concurrent requests that being triggered by clicking the &quot;New Quote&quot; button continuously" width="600" height="400" loading="lazy">
<em>Concurrent requests that being triggered by clicking the "New Quote" button continuously</em></p>
<p>As you see in the GIF above, when I click the "New Quote" button consecutively, I have to wait for all requests to be done to see a random quote because SWR only updates the data after the last request is completed.</p>
<p>As a result, I should cancel the ongoing previous request after a new request is initiated. Although I checked SWR's documentation, I couldn't find a built-in solution for this issue. I tried to use <code>AbortController</code> with SWR, but couldn't succeed.</p>
<p>As a workaround, I disabled the <code>New Quote</code> button during validation to be able to prevent multiple concurrent requests.</p>
<p>A little note: I also checked <a target="_blank" href="https://tanstack.com/query/latest">React Query</a>, and it has a built-in solution for that. I am planning to experiment with it in my next project involving remote data.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>React doesn't care how you fetch and manage remote data. In this tutorial, you have learned how to do this with SWR. Although it has a big drawback regarding canceling concurrent requests, you can usually work around this and benefit from its upsides.</p>
<p>If you haven't used SWR before, I highly recommend trying it out in your future projects. It saves you time and prevents you from experiencing many types of bugs.</p>
<p>Thank you for reading. You can connect with me on <a target="_blank" href="https://twitter.com/femincan">Twitter</a> or explore more on <a target="_blank" href="https://femincan.dev">my personal website</a>. Feel free to reach out — I'd love to hear from you!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ React Lifecycle Methods and Hooks – a Beginner's Guide ]]>
                </title>
                <description>
                    <![CDATA[ React is all about building user interfaces. And to do that effectively, React provides ways for components to manage their lifecycles. This means that components can perform specific tasks at different stages of their existence, from the moment they... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/react-lifecycle-methods-and-hooks-for-beginners/</link>
                <guid isPermaLink="false">66d45e08680e33282da25e59</guid>
                
                    <category>
                        <![CDATA[ hooks ]]>
                    </category>
                
                    <category>
                        <![CDATA[ lifecycle methods ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                    <category>
                        <![CDATA[ react hooks ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Casmir Onyekani ]]>
                </dc:creator>
                <pubDate>Mon, 02 Oct 2023 17:22:49 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/10/lifecycle.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p><a target="_blank" href="https://www.freecodecamp.org/news/react-beginner-handbook/#howmuchjavascriptyouneedtoknowtousereact">React</a> is all about building user interfaces. And to do that effectively, React provides ways for components to manage their lifecycles.</p>
<p>This means that components can perform specific tasks at different stages of their existence, from the moment they are created to the point they are removed from the user interface.</p>
<p>Lifecycle methods have been a fundamental part of React for many years. But with the introduction of hooks, React's approach to managing state and side effects in functional components has become more intuitive and flexible.</p>
<p>Just a quick note: although hooks generally replace class components, there are no plans to remove classes from React.</p>
<h3 id="heading-why-this-guide">Why This Guide?</h3>
<p>In this tutorial, you will learn about class component lifecycle methods such as <code>componentDidMount</code>, <code>componentDidUpdate</code>, <code>componentWillUnmount</code>, and <code>shouldComponentUpdate</code>.</p>
<p>You'll also explore React hooks like <code>useState</code>, <code>useEffect</code>, and <code>useContext</code>, and understand why they were introduced. This will make your React journey smoother and more enjoyable.</p>
<p>Whether you're just getting started with React or looking to deepen your understanding, this guide will equip you with the knowledge you need to build responsive and interactive web applications using React's powerful tools.</p>
<p>Let's dive in and uncover the magic of React lifecycle methods and hooks.</p>
<h2 id="heading-how-the-component-lifecycle-works">How the Component Lifecycle Works</h2>
<p>In React, components go through a lifecycle composed of distinct stages. Each of these stages offers specific methods that you can customize to run code at various moments during a component's existence.</p>
<p>These methods help you perform tasks such as initializing data, managing updates, and tidying up resources as needed.</p>
<h3 id="heading-class-component-lifecycle-methods">Class Component Lifecycle Methods</h3>
<p>Let's start by looking at the class component lifecycle methods. These were the primary way to manage component lifecycle before the introduction of hooks.</p>
<h4 id="heading-how-to-use-componentdidmount">How to use <code>componentDidMount</code>:</h4>
<p>This is called after a component has been inserted into the DOM. It's a great place to perform initial setup tasks, like fetching data from an API or setting up event listeners.</p>
<p>Code example:</p>
<pre><code class="lang-jsx">
<span class="hljs-keyword">import</span> React, { Component } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MyComponent</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">React</span>.<span class="hljs-title">Component</span> </span>{
  <span class="hljs-keyword">constructor</span>() {
    <span class="hljs-built_in">super</span>();
    <span class="hljs-built_in">this</span>.state = {
      <span class="hljs-attr">data</span>: <span class="hljs-literal">null</span>,
    };
  }

  componentDidMount() {
    <span class="hljs-comment">// This is where you can perform initial setup.</span>

    <span class="hljs-comment">// In this example, we simulate fetching data from an API after the             component has mounted.</span>
    <span class="hljs-comment">// We use a setTimeout to mimic an asynchronous operation.</span>
    <span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">() =&gt;</span> {
      <span class="hljs-keyword">const</span> fetchedData = <span class="hljs-string">'This data was fetched after mounting.'</span>;
      <span class="hljs-built_in">this</span>.setState({ <span class="hljs-attr">data</span>: fetchedData });
    }, <span class="hljs-number">2000</span>); <span class="hljs-comment">// Simulate a 2-second delay</span>
  }

  render() {
    <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">h1</span>&gt;</span>componentDidMount Example<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
        {this.state.data ? (
          <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Data: {this.state.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 data...<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>
    );
  }
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> MyComponent;
</code></pre>
<p>In this example, we created a class component called <code>MyComponent</code>. In the constructor, the component's state is initialized with data set to null, and we use it to store the fetched data.</p>
<p>In the <code>componentDidMount</code> method, we simulate fetching data from an API using <code>setTimeout</code> to mimic an asynchronous operation. After 2 seconds (2000 milliseconds), the component's state updates with the fetched data.</p>
<p>In the render method, content is conditionally rendered based on the data state. If data is null, a <code>Loading data...</code> message is displayed. Otherwise, the fetched data is displayed.</p>
<p>When you use this component in your application, you'll notice that the Loading data... message is shown initially, and after 2 seconds, the fetched data is displayed. This demonstrates how <code>componentDidMount</code> is useful for performing tasks after a component has been added to the DOM.</p>
<h4 id="heading-how-to-use-componentdidupdateb">How to use <code>componentDidUpdate</code>B:</h4>
<p>This is called after a component has re-rendered due to changes in its state or props. It's a great place to handle side effects or perform additional actions based on those changes.</p>
<p>Code Example:</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> React, { Component } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Counter</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">React</span>.<span class="hljs-title">Component</span> </span>{
  <span class="hljs-keyword">constructor</span>() {
    <span class="hljs-built_in">super</span>();
    <span class="hljs-built_in">this</span>.state = {
      <span class="hljs-attr">count</span>: <span class="hljs-number">0</span>,
    };
  }

  <span class="hljs-comment">// This method will be called when the "Increment" button is clicked</span>
  handleIncrement = <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-built_in">this</span>.setState({ <span class="hljs-attr">count</span>: <span class="hljs-built_in">this</span>.state.count + <span class="hljs-number">1</span> });
  };

  <span class="hljs-comment">// componentDidUpdate is called after the component updates</span>
  componentDidUpdate(prevProps, prevState) {
    <span class="hljs-comment">// You can access the previous props and state here</span>
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Component updated'</span>);
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Previous state:'</span>, prevState);
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Current state:'</span>, <span class="hljs-built_in">this</span>.state);
  }

  render() {
    <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">h1</span>&gt;</span>Counter<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Count: {this.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">{this.handleIncrement}</span>&gt;</span>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>
    );
  }
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> Counter;
</code></pre>
<p>In this code example, we create a <code>Counter</code> class component with a constructor that initializes the <code>count</code> state to 0. The <code>handleIncrement</code> method updates the count state when the <em>Increment</em> button is clicked.</p>
<p>Inside the <code>componentDidUpdate</code> lifecycle method, we log a message (Component updated) to the console. We also log both the previous state (prevState) and the current state (this.state). This demonstrates how you can access both the previous and current values during an update. The render method displays the current count and a button to increment it.</p>
<p>Now, when you use this <code>Counter</code> component in your application, open the browser's console. Every time you click the <em>Increment</em> button, you'll see messages in the console indicating that the component has updated, along with the previous and current state values.</p>
<p>You can use <code>componentDidUpdate</code> for various purposes, such as making network requests when props or state change, updating the DOM based on state changes, or interacting with third-party libraries after an update. It provides a way to perform actions that should occur specifically after a component has re-rendered.</p>
<h4 id="heading-how-to-use-componentwillunmount">How to use <code>componentWillUnmount</code></h4>
<p>This is called just before a component is removed from the DOM. It's a crucial place to perform cleanup tasks, such as clearing timers, unsubscribing from events, or releasing resources to prevent [memory leaks](https://en.wikipedia.org/wiki/Memory_leak#:~:text=In computer science%2C a memory,longer needed is not released.).</p>
<p>Let's illustrate a simple React component that sets up a timer when it mounts, using <code>componentDidMount</code> method, and clears that timer when it unmounts using the <code>componentWillUnmount</code> method.</p>
<p>Code example:</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> React, { Component } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">TimerComponent</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">React</span>.<span class="hljs-title">Component</span> </span>{
  <span class="hljs-keyword">constructor</span>() {
    <span class="hljs-built_in">super</span>();
    <span class="hljs-built_in">this</span>.state = {
      <span class="hljs-attr">seconds</span>: <span class="hljs-number">0</span>,
    };
    <span class="hljs-built_in">this</span>.timer = <span class="hljs-literal">null</span>; <span class="hljs-comment">// Initialize the timer</span>
  }

  <span class="hljs-comment">// When the component mounts, start the timer</span>
  componentDidMount() {
    <span class="hljs-built_in">this</span>.timer = <span class="hljs-built_in">setInterval</span>(<span class="hljs-function">() =&gt;</span> {
      <span class="hljs-built_in">this</span>.setState({ <span class="hljs-attr">seconds</span>: <span class="hljs-built_in">this</span>.state.seconds + <span class="hljs-number">1</span> });
    }, <span class="hljs-number">1000</span>); <span class="hljs-comment">// Update every 1 second (1000 milliseconds)</span>
  }

  <span class="hljs-comment">// When the component unmounts, clear the timer to prevent memory leaks</span>
  componentWillUnmount() {
    <span class="hljs-built_in">clearInterval</span>(<span class="hljs-built_in">this</span>.timer);
  }

  render() {
    <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">h1</span>&gt;</span>Timer Component<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Elapsed Time: {this.state.seconds} seconds<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>
    );
  }
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> TimerComponent;
</code></pre>
<p>In this example, we created the <code>TimerComponent</code> class. Inside the constructor, the component's state is initialized with a seconds property, which we'll use to keep track of the elapsed time. The timer variable is also set to null.</p>
<p>In the <code>componentDidMount</code> lifecycle method, the timer is started by using <code>setInterval</code>. This timer increments the seconds state property every second.</p>
<p>In the <code>componentWillUnmount</code> lifecycle method, the timer is cleared using <code>clearInterval</code> to ensure that it doesn't continue running after the component has been removed from the DOM.</p>
<p>In the render method, the elapsed time is displayed based on the seconds state property.</p>
<p>When you use this <code>TimerComponent</code> in your application and render it, you'll notice that the timer starts when the component is mounted and stops when the component is unmounted. This is thanks to the cleanup performed in the <code>componentWillUnmount</code> method. This prevents resource leaks and ensures that<br>the timer is properly managed throughout the component's lifecycle.</p>
<h4 id="heading-how-to-use-shouldcomponentupdate">How to use <code>shouldComponentUpdate</code></h4>
<p>We use this lifecycle method to control whether a component should re-render when its state or props change. It is particularly useful for optimizing performance by preventing unnecessary renders.</p>
<p>Let's create a simple React class component and use the <code>shouldComponentUpdate</code> method to decide whether the component should re-render based on changes in its state.</p>
<p>Code Example:</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> React, { Component } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Counter</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">React</span>.<span class="hljs-title">Component</span> </span>{
  <span class="hljs-keyword">constructor</span>() {
    <span class="hljs-built_in">super</span>();
    <span class="hljs-built_in">this</span>.state = {
      <span class="hljs-attr">count</span>: <span class="hljs-number">0</span>,
    };
  }

  shouldComponentUpdate(nextProps, nextState) {
    <span class="hljs-comment">// Allow the component to re-render only if the count is even</span>
    <span class="hljs-keyword">if</span> (nextState.count % <span class="hljs-number">2</span> === <span class="hljs-number">0</span>) {
      <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>; <span class="hljs-comment">// Re-render</span>
    }
    <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>; <span class="hljs-comment">// Don't re-render</span>
  }

  incrementCount = <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-built_in">this</span>.setState(<span class="hljs-function">(<span class="hljs-params">prevState</span>) =&gt;</span> ({ <span class="hljs-attr">count</span>: prevState.count + <span class="hljs-number">1</span> }));
  };

  render() {
    <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">h1</span>&gt;</span>Counter Example<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Count: {this.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">{this.incrementCount}</span>&gt;</span>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>
    );
  }
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> Counter;
</code></pre>
<p>In this example, we created the <code>Counter</code> class component that maintains a count state, which starts at 0. In the <code>shouldComponentUpdate</code> method, we check whether the next state's count is even. If it is, we allow the component to re-render. Otherwise, we prevent the re-render.</p>
<p>The <code>incrementCount</code> method is called when the <em>Increment</em> button is clicked. It updates the count state by incrementing it.</p>
<p>In the render method, the current count and a button to increment it is displayed.</p>
<p>If you click the <em>Increment</em> button and the count becomes an odd number, the component won't re-render. This behavior demonstrates how <code>shouldComponentUpdate</code> can be used to optimize rendering in situations where not all state changes should trigger a re-render.</p>
<h2 id="heading-introducing-react-hooks">Introducing React Hooks</h2>
<p>React introduced hooks in version 16.8. They granted functional components access to state and various React features without writing class components.</p>
<p>As a result, class components have become largely unnecessary. Hooks simplify component logic and make it more reusable.</p>
<h3 id="heading-why-use-hooks">Why use Hooks?</h3>
<p>Hooks were introduced to address several issues and make React code easier to understand and maintain:</p>
<ul>
<li><p>Complexity – class components can become complex when managing state and side effects.</p>
</li>
<li><p>Reusability – logic in class components isn't easily shareable between components.</p>
</li>
<li><p>Learning Curve – class components introduce a steeper learning curve for newcomers to React.</p>
</li>
</ul>
<h3 id="heading-commonly-used-react-hooks">Commonly used React Hooks</h3>
<h4 id="heading-the-usestate-hook">The <code>useState</code> hook</h4>
<p><code>useState</code> lets you add state to functional components. It returns an array with the current state value and a function to update it.</p>
<p>Code Example:</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> React, { 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">Counter</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>In this example, we used the <code>useState</code> hook to manage a counter's state. When the Increment button is clicked, <code>setCount</code> updates the count state, causing the component to re-render with the updated value.</p>
<h4 id="heading-the-useeffect-hook">The <code>useEffect</code> hook</h4>
<p><code>useEffect</code> is used for side effects in functional components, similar to <code>componentDidMount</code> and <code>componentDidUpdate</code>. It runs after rendering and can be controlled by specifying dependencies.</p>
<p>Code Example:</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> React, { useState, useEffect } <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">Example</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [data, setData] = useState(<span class="hljs-literal">null</span>);

  useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-comment">// Fetch data from an API</span>
    fetch(<span class="hljs-string">'https://api.example.com/data'</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));
  }, []); <span class="hljs-comment">// Empty dependency array, runs only once</span>

  <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>{data ? data.message : 'Loading...'}<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>;
}
</code></pre>
<p>In this example, <code>useEffect</code> is used to fetch data from an API when the component mounts. The empty dependency array <code>[]</code> ensures that the effect runs only once.<br>When the data is fetched, <code>setData</code> updates the data state, causing a re-render with the fetched information.</p>
<h4 id="heading-the-usecontext-hook">The <code>useContext</code> hook</h4>
<p><code>useContext</code> allows functional components to access context values. It's a way to pass data down the component tree without explicitly passing props.</p>
<p>Code Example:</p>
<pre><code class="lang-jsx">
<span class="hljs-keyword">import</span> React, { useContext } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-comment">// Create a context</span>
<span class="hljs-keyword">const</span> MyContext = React.createContext();

<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> value = useContext(MyContext);

  <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>Context Value: {value}<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>;
}
</code></pre>
<p>In this example, we create a context called <code>MyContext</code>. The <code>useContext</code> hook allows <code>MyComponent</code> to access the value stored in this context. It's a powerful tool for managing global state in your application.</p>
<h3 id="heading-benefits-of-custom-hooks">Benefits of custom hooks</h3>
<p>Custom hooks are functions that use hooks internally and can be reused across multiple components. They help encapsulate and share complex logic.</p>
<p>Here's an example of a custom hook called <code>useLocalStorage</code> that simplifies storing and retrieving data in the browser's local storage:</p>
<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">useLocalStorage</span>(<span class="hljs-params">key, initialValue</span>) </span>{
  <span class="hljs-comment">// Retrieve the stored value from local storage</span>
  <span class="hljs-keyword">const</span> storedValue = <span class="hljs-built_in">localStorage</span>.getItem(key);

  <span class="hljs-comment">// Initialize the state with the stored value or the initial value</span>
  <span class="hljs-keyword">const</span> [value, setValue] = useState(storedValue || initialValue);

  <span class="hljs-comment">// Update the local storage whenever the state changes</span>
  <span class="hljs-keyword">const</span> setStoredValue = <span class="hljs-function">(<span class="hljs-params">newValue</span>) =&gt;</span> {
    setValue(newValue);
    <span class="hljs-built_in">localStorage</span>.setItem(key, newValue);
  };

  <span class="hljs-keyword">return</span> [value, setStoredValue];
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> useLocalStorage;
</code></pre>
<p>In this custom hook, we import <code>useState</code> from React because we'll use it to manage the state. The <code>useLocalStorage</code> function takes two parameters:</p>
<ul>
<li><p><strong>key</strong>: A string representing the key under which the data will be stored in local storage.</p>
</li>
<li><p><code>**initialValue**</code>: The initial value for the state.</p>
</li>
</ul>
<p>Inside the hook, we first attempted to retrieve the stored value from local storage using <code>localStorage.getItem(key)</code>. Then we initialized the state variable value using <code>useState</code>, using the <code>storedValue</code> if it exists or the <code>initialValue</code> if not.</p>
<p>Next, we defined a function <code>setStoredValue</code> that updates both the state and the local storage when called. It sets the new value in local storage using <code>localStorage.setItem(key, newValue)</code>.</p>
<p>Finally, we returned an array <code>[value, setStoredValue]</code> as the hook's return value, allowing components to access the stored value and update it as needed.</p>
<p>Here's an example of how you can use the <code>useLocalStorage</code> hook in a component:</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
<span class="hljs-keyword">import</span> useLocalStorage <span class="hljs-keyword">from</span> <span class="hljs-string">'./useLocalStorage'</span>; <span class="hljs-comment">// Import the custom hook</span>

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-comment">// Use the custom hook to manage a "username" stored in local storage</span>
  <span class="hljs-keyword">const</span> [username, setUsername] = useLocalStorage(<span class="hljs-string">'username'</span>, <span class="hljs-string">'Guest'</span>);

  <span class="hljs-keyword">const</span> handleInputChange = <span class="hljs-function">(<span class="hljs-params">e</span>) =&gt;</span> {
    setUsername(e.target.value);
  };

  <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">h1</span>&gt;</span>Hello, {username}!<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">input</span>
        <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span>
        <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"Enter your username"</span>
        <span class="hljs-attr">value</span>=<span class="hljs-string">{username}</span>
        <span class="hljs-attr">onChange</span>=<span class="hljs-string">{handleInputChange}</span>
      /&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> App;
</code></pre>
<p>In this example, we import the <code>useLocalStorage</code> custom hook and use it to manage a username value in local storage. The component initializes the username state using the hook and updates it when the input field changes.</p>
<p>The value is stored and retrieved from local storage, allowing it to persist across page reloads.</p>
<p>Custom hooks are a powerful way to encapsulate and reuse complex logic in React applications, making your code more modular and maintainable.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>React provides developers with powerful tools to manage the lifecycles of their components. These lifecycles allow components to perform specific tasks at different stages of their existence, from creation to removal.</p>
<p>In this guide, we've explored React's class component lifecycle methods. These methods have been a fundamental part of React for many years and continue to be relevant in certain scenarios.</p>
<p>You've also been introduced to React Hooks. These have become the preferred way to manage state and side effects in React applications. They offer a more intuitive and flexible approach to building components.</p>
<p>While hooks have gained popularity and generally replace the need for class components, it's important to note that there are no plans to remove class components from React. Existing codebases and third-party libraries may still use class components, so understanding both class component lifecycles and hooks is<br>valuable for React developers.</p>
<p>In summary, React's lifecycle methods and hooks are crucial for building dynamic and efficient applications, and they offer developers a range of options to manage component behavior and state. As you continue to explore and work with React,<br>you'll find that having a solid understanding of both lifecycles and hooks will make you a more versatile and capable React developer.</p>
<p>If you found this guide helpful and enjoyable, please give it a like. For more insightful tutorials, follow me on <a target="_blank" href="https://twitter.com/casweb_dev">X</a> for updates 🙏.</p>
<p>Enjoy your coding!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ React Hooks You Can Use in Every Project – Explained with Examples ]]>
                </title>
                <description>
                    <![CDATA[ Hooks are one of the most powerful features of React.  They enable us to easily reuse functionality across our application's components. What's best about hooks is their reusability – you can reuse your hooks both across components and your projects.... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/react-hooks-every-project-should-use/</link>
                <guid isPermaLink="false">66d037c3ccf811d3117aeeed</guid>
                
                    <category>
                        <![CDATA[ hooks ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Reed ]]>
                </dc:creator>
                <pubDate>Fri, 06 Jan 2023 19:23:16 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/01/7-react-hooks.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Hooks are one of the most powerful features of React. </p>
<p>They enable us to easily reuse functionality across our application's components. What's best about hooks is their reusability – you can reuse your hooks both across components and your projects.</p>
<p>Here are seven of the most important React hooks that I reuse across every react project I create. Give them a try today and see if they're as useful for you when building your own React apps.</p>
<p>Before we begin, it's important to clarify that not every custom React hook needs to be written by you. In fact, all of the hooks that I will mention come from the library <code>@mantine/hooks</code>. </p>
<p>Mantine is great third-party library that includes these hooks and many more. They will add just about every significant feature to your React app that you can think of.</p>
<p>You can check out the documentation for <code>@mantine/hooks</code> at <a target="_blank" href="https://mantine.dev">mantine.dev</a>.</p>
<h2 id="heading-the-useintersection-hook">The <code>useIntersection</code> Hook</h2>
<p>When a user scrolls down the page in your application, you may want to know when an element is visible to them. </p>
<p>For example, you might want to start an animation only when a user sees a specific element. Or, you may want to show or hide an element after they've scrolled a certain amount down the page. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/01/use-intersection.gif" alt="Image" width="600" height="400" loading="lazy">
<em>useIntersection demo</em></p>
<p>To get information about whether an element is visible, we can use the <strong>Intersection Observer API.</strong> This is a JavaScript API that's built into the browser. </p>
<p>We can use the API on its own using plain JavaScript, but a great way to get information about whether a particular element is being intersected within its scroll container is to use the <code>useIntersection</code> hook. </p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> { useRef } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
<span class="hljs-keyword">import</span> { useIntersection } <span class="hljs-keyword">from</span> <span class="hljs-string">'@mantine/hooks'</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Demo</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> containerRef = useRef();
  <span class="hljs-keyword">const</span> { ref, entry } = useIntersection({
    <span class="hljs-attr">root</span>: containerRef.current,
    <span class="hljs-attr">threshold</span>: <span class="hljs-number">1</span>,
  });

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">main</span> <span class="hljs-attr">ref</span>=<span class="hljs-string">{containerRef}</span> <span class="hljs-attr">style</span>=<span class="hljs-string">{{</span> <span class="hljs-attr">overflowY:</span> '<span class="hljs-attr">scroll</span>', <span class="hljs-attr">height:</span> <span class="hljs-attr">300</span> }}&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">ref</span>=<span class="hljs-string">{ref}</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span>
          {entry?.isIntersecting ? 'Fully visible' : 'Obscured'}
        <span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">main</span>&gt;</span></span>
  );
}
</code></pre>
<p>To use it, all we need to do is call the hook in our component and provide a root element. Root is the scroll container, and this can be provided as a ref with the <code>useRef</code> hook. <code>useIntersection</code> returns a ref which we pass to the target element, whose intersection in the scroll container we want to observe.</p>
<p>Once we have a reference to the element, we can keep track of whether the element is intersecting or not. In the example above, we can see when the element is obscured or when it's fully visible based off the value of <code>entry.isIntersecting</code>. </p>
<p>You can pass additional arguments that allow you to configure the <strong>threshold</strong> which is related to what percentage of the target is visible.</p>
<h2 id="heading-the-usescrolllock-hook">The <code>useScrollLock</code> Hook</h2>
<p>Another hook related to scrolling is the <code>useScrollLock</code> hook. This hook is very simple: it enables you to lock any scrolling on the body element. </p>
<p>I have found it to be helpful whenever you want to display an overlay or a modal over the current page and do not want to allow the user to scroll up and down on the page in the background. This lets you either focus attention on the modal or allow scrolling within its own scroll container.</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> { useScrollLock } <span class="hljs-keyword">from</span> <span class="hljs-string">'@mantine/hooks'</span>;
<span class="hljs-keyword">import</span> { Button, Group } <span class="hljs-keyword">from</span> <span class="hljs-string">'@mantine/core'</span>;
<span class="hljs-keyword">import</span> { IconLock, IconLockOpen } <span class="hljs-keyword">from</span> <span class="hljs-string">'@tabler/icons'</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Demo</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [scrollLocked, setScrollLocked] = useScrollLock();

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Group</span> <span class="hljs-attr">position</span>=<span class="hljs-string">"center"</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> setScrollLocked((c) =&gt; !c)}
        variant="outline"
        leftIcon={scrollLocked ? <span class="hljs-tag">&lt;<span class="hljs-name">IconLock</span> <span class="hljs-attr">size</span>=<span class="hljs-string">{16}</span> /&gt;</span> : <span class="hljs-tag">&lt;<span class="hljs-name">IconLockOpen</span> <span class="hljs-attr">size</span>=<span class="hljs-string">{16}</span> /&gt;</span>}
      &gt;
        {scrollLocked ? 'Unlock scroll' : 'Lock scroll'}
      <span class="hljs-tag">&lt;/<span class="hljs-name">Button</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">Group</span>&gt;</span></span>
  );
}
</code></pre>
<p><code>useScrollLock</code> locks the user's scroll at their current position on the page. The function returns an array, which can be destructured, as in the code above. </p>
<p>The second value is a function that allows us to lock the scroll. The first destructured value, on the other hand, is a boolean that tells us whether the scroll has been locked or not. </p>
<p>This value is useful for example, if you want to show certain content when the scroll is locked or to tell the user that it has been locked. You can see in the example below that we are indicating within our button when the scroll has been locked or unlocked.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/01/use-scroll-lock.gif" alt="Image" width="600" height="400" loading="lazy">
<em>useScrollLock demo</em></p>
<h2 id="heading-the-useclipboard-hook">The <code>useClipboard</code> Hook</h2>
<p>In many cases, you want to provide a button that allows the user to copy something to their clipboard, which is where copied text is stored. </p>
<p>A great example of this is if you have a code snippet on your website and you want to users to easily copy it. For this, we can use another web API – the <strong>Clipboard API</strong>. </p>
<p><code>@mantine/hooks</code> gives us a convenient <code>useClipboard</code> hook, which returns a couple of properties: <code>copied</code>, which is a boolean that tells us whether a value has been copied to the clipboard using the hook as well as a <code>copy</code> function, to which we can pass whatever string value we like to it to be copied. </p>
<p>In our example, we would like to copy a code snippet for our users to paste where they like, as seen in the video below: </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/01/use-clipboard.gif" alt="Image" width="600" height="400" loading="lazy">
<em>useClipboard demo</em></p>
<p>We call our <code>copy</code> function when they hit our designated copy button, pass to it the code snippet, and then show a little checkmark or something that indicates to them that the text has been copied. </p>
<p>What's neat is the <code>useClipboard</code> hook comes with a <strong>timeout value</strong>. After a given timeout period, which is in milliseconds, the copied state will be reset, showing the user that they can copy the text again.</p>
<h2 id="heading-the-usedebouncedvalue-hook">The <code>useDebouncedValue</code> Hook</h2>
<p>The next hook, <code>useDebouncedValue</code>, is essential if you have a search input in your app.</p>
<p>Whenever a user performs a search using an input, the search operation usually involves an HTTP request to an API. </p>
<p>A typical problem you will encounter, especially if you want your users to receive search results as they are typing, is that a query (request) will be performed on every keystroke. Even for a simple search query, there is no need to perform so many requests before a user has finished typing what they want. </p>
<p>This is a great use case for the <code>useDebounceValue</code> hook, which applies a debounce function on the text that's has been passed to it. </p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> { useState } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
<span class="hljs-keyword">import</span> { useDebouncedValue } <span class="hljs-keyword">from</span> <span class="hljs-string">'@mantine/hooks'</span>;
<span class="hljs-keyword">import</span> { getResults } <span class="hljs-keyword">from</span> <span class="hljs-string">'api'</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Demo</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [value, setValue] = useState(<span class="hljs-string">''</span>);
  <span class="hljs-keyword">const</span> [results, setResults] = useState([])
  <span class="hljs-keyword">const</span> [debounced] = useDebouncedValue(value, <span class="hljs-number">200</span>); <span class="hljs-comment">// wait time of 200 ms</span>

  useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">if</span> (debounced) {
      handleGetResults() 
    }

    <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handleGetResults</span>(<span class="hljs-params"></span>) </span>{
       <span class="hljs-keyword">const</span> results = <span class="hljs-keyword">await</span> getResults(debounced)   
       setResults(results)
    }
  }, [debounced])

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">input</span>
        <span class="hljs-attr">label</span>=<span class="hljs-string">"Enter search query"</span>
        <span class="hljs-attr">value</span>=<span class="hljs-string">{value}</span>
        <span class="hljs-attr">style</span>=<span class="hljs-string">{{</span> <span class="hljs-attr">flex:</span> <span class="hljs-attr">1</span> }}
        <span class="hljs-attr">onChange</span>=<span class="hljs-string">{(event)</span> =&gt;</span> setValue(event.currentTarget.value)}
      /&gt;
      <span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span>{results.map(result =&gt; <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>{result}<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>}<span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>
    <span class="hljs-tag">&lt;/&gt;</span></span>
  );
}
</code></pre>
<p>You store the text from your input in a piece of state with <code>useState</code> and pass the state variable to <code>useDebouncedValue</code>. </p>
<p>As the second argument to that hook, you can provide a wait time, which is the period of time that the value is debounced. The debounce is what enables us to perform far fewer queries.</p>
<p>You can see the result in the video below where the user types something and only after 200 milliseconds, do we see the debounced value.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/01/use-debounced-value.gif" alt="Image" width="600" height="400" loading="lazy">
<em>useDebouncedValue demo</em></p>
<h2 id="heading-the-usemediaquery-hook">The <code>useMediaQuery</code> Hook</h2>
<p>Another very useful hook that I use all the time is the <code>useMediaQuery</code> hook. </p>
<p>Media Queries are used in plain CSS and the <code>useMediaQuery</code> hook allows us to subscribe to whatever media query we pass to the hook. </p>
<p>For example, within our component, let's say that we want to show some text or change the styles of a component based off of a certain screen width, such as 900 pixels. We provide a media query just like we would in CSS and <code>useMediaQuery</code> returns to us a <code>matches</code> value which is either true or false.</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> { useMediaQuery } <span class="hljs-keyword">from</span> <span class="hljs-string">'@mantine/hooks'</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Demo</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> matches = useMediaQuery(<span class="hljs-string">'(min-width: 900px)'</span>);

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">style</span>=<span class="hljs-string">{{</span> <span class="hljs-attr">color:</span> <span class="hljs-attr">matches</span> ? '<span class="hljs-attr">teal</span>' <span class="hljs-attr">:</span> '<span class="hljs-attr">red</span>' }}&gt;</span>
      {matches ? 'I am teal' : 'I am red'}
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}
</code></pre>
<p>It tells us the result of that media query in JavaScript, which is particularly useful when we have styles that we want to change directly within our JSX using the <code>style</code> prop, for example. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/01/use-media-query.gif" alt="Image" width="600" height="400" loading="lazy">
<em>useMediaQuery</em></p>
<p>In short, this is an essential hook for those handful of cases in which CSS cannot be used to handle media queries. </p>
<h2 id="heading-the-useclickoutside-hook">The <code>useClickOutside</code> Hook</h2>
<p>This next hook – <code>useClickOutside</code> – might seem like a strange one, but you'll see how important it is when you actually need it. </p>
<p>When you develop a dropdown or something that pops up in front of a page's content and needs to be closed afterwards (such as a modal or drawer), this hook is indispensable. It's very easy to open one of these types of components by clicking a button. Closing these components is a little harder. </p>
<p>To follow good UX practices, we want anything that obstructs our user's view to be easily closable by clicking outside of the element. This is specifically what the <code>useClickOutside</code> hook lets us do. </p>
<p>When we call <code>useClickOutside</code>, it returns a ref that we must pass to the element outside of which we want to detect clicks. Usually that element is going to be controlled by a boolean piece of state such as the one we have in our example below (that is, the value <code>opened</code>). </p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> { useState } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
<span class="hljs-keyword">import</span> { useClickOutside } <span class="hljs-keyword">from</span> <span class="hljs-string">'@mantine/hooks'</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Demo</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [opened, setOpened] = useState(<span class="hljs-literal">false</span>);
  <span class="hljs-keyword">const</span> ref = useClickOutside(<span class="hljs-function">() =&gt;</span> setOpened(<span class="hljs-literal">false</span>));

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;&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> setOpened(true)}&gt;Open dropdown<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
      {opened &amp;&amp; (
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">ref</span>=<span class="hljs-string">{ref}</span> <span class="hljs-attr">shadow</span>=<span class="hljs-string">"sm"</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span>Click outside to close<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
      )}
    <span class="hljs-tag">&lt;/&gt;</span></span>
  );
}
</code></pre>
<p><code>useClickOutside</code> accepts a callback function which controls what happens when you actually click outside that element. </p>
<p>In most cases, we want to do something quite simple, which is to just close it. To do so, you'll likely need to have a state setter (like <code>setOpened</code>) and pass it a value of false to then hide your overlayed content.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/01/use-click-outside.gif" alt="Image" width="600" height="400" loading="lazy">
<em>useClickOutside demo</em></p>
<h2 id="heading-the-useform-hook">The <code>useForm</code> Hook</h2>
<p>My favorite and most helpful hook in this list is the <code>useForm</code> hook. </p>
<p>This hook comes specifically from Mantine and involves installing a specific package from the library: <code>@mantine/form</code>. It should give you everything that you need to create forms in React, including the ability to validate inputs, display error messages, and ensure the input values are correct before the form is submitted.</p>
<p><code>useForm</code> accepts some initial values which correspond to whatever inputs you have within your form.</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> { TextInput, Button } <span class="hljs-keyword">from</span> <span class="hljs-string">'@mantine/core'</span>;
<span class="hljs-keyword">import</span> { useForm } <span class="hljs-keyword">from</span> <span class="hljs-string">'@mantine/form'</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Demo</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> form = useForm({
    <span class="hljs-attr">initialValues</span>: {
      <span class="hljs-attr">email</span>: <span class="hljs-string">''</span>
    },

    <span class="hljs-attr">validate</span>: {
      <span class="hljs-attr">email</span>: <span class="hljs-function">(<span class="hljs-params">value</span>) =&gt;</span> (<span class="hljs-regexp">/^\S+@\S+$/</span>.test(value) ? <span class="hljs-literal">null</span> : <span class="hljs-string">'Invalid email'</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">form</span> <span class="hljs-attr">onSubmit</span>=<span class="hljs-string">{form.onSubmit((values)</span> =&gt;</span> console.log(values))}&gt;
        <span class="hljs-tag">&lt;<span class="hljs-name">TextInput</span>
          <span class="hljs-attr">withAsterisk</span>
          <span class="hljs-attr">label</span>=<span class="hljs-string">"Email"</span>
          <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"your@email.com"</span>
          {<span class="hljs-attr">...form.getInputProps</span>('<span class="hljs-attr">email</span>')}
        /&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">Button</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"submit"</span>&gt;</span>Submit<span class="hljs-tag">&lt;/<span class="hljs-name">Button</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}
</code></pre>
<p>The great benefit of <code>useForm</code> is its helpers, such as the <code>validate</code> function, which receives the value that's been typed in to each input then allows you to create validation rules. </p>
<p>For example, if you have an email input, you might have a regular expression to determine whether it is in fact a valid email (as you can see in the code above). If not, then you can show an error message and prevent the form from being submitted. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/01/use-form.gif" alt="Image" width="600" height="400" loading="lazy">
<em>useForm demo</em></p>
<p>How do you get the values that have been typed into the form? </p>
<p>Mantine provides a very convenient helper called <code>getInputProps</code>, where you simply provide the name of the input you're working with (like email) and it automatically sets up an onChange to keep track of the values that you've typed into your form. </p>
<p>Additionally, to handle form submission and prevent submission if its values do not pass validation rules, it has a special <code>onSubmit</code> function which you wrap around your regular onSubmit function. On top of applying the validation rules, it will take care of calling <code>preventDefault()</code> on the form event so that you don't have to do it manually. </p>
<p>I am just scratching the surface with this hook, but I would highly recommend you use it for your next project. Forms are traditionally a pain to get working properly, especially forms that require validation and visible error messages. <code>useForm</code> makes it incredibly easy!</p>
<h2 id="heading-become-a-professional-react-developer">Become a Professional React Developer</h2>
<p>React is hard. You shouldn't have to figure it out yourself.</p>
<p>I've put everything I know about React into a single course, to help you reach your goals in record time:</p>
<p><a target="_blank" href="https://www.thereactbootcamp.com"><strong>Introducing: The React Bootcamp</strong></a></p>
<p><strong>It’s the one course I wish I had when I started learning React.</strong></p>
<p>Click below to try the React Bootcamp for yourself:</p>
<p><a target="_blank" href="https://www.thereactbootcamp.com"><img src="https://reedbarger.nyc3.digitaloceanspaces.com/reactbootcamp/react-bootcamp-cta-alt.png" alt="Click to join the React Bootcamp" width="600" height="400" loading="lazy"></a>
<em>Click to get started</em></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Separation of Concerns in React –How to Use Container and Presentational Components ]]>
                </title>
                <description>
                    <![CDATA[ Many new React developers combine logic and presentation inside the same React component. And they may not know why it's important to separate these two – they just want to make it work.  But later, they'll find that they need to make changes to the ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/separation-of-concerns-react-container-and-presentational-components/</link>
                <guid isPermaLink="false">66bb55554c9d249e52882f2f</guid>
                
                    <category>
                        <![CDATA[ components ]]>
                    </category>
                
                    <category>
                        <![CDATA[ hooks ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Keyur Paralkar ]]>
                </dc:creator>
                <pubDate>Tue, 06 Dec 2022 21:43:19 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/12/container-and-presentational-component-pattern-image.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Many new React developers combine logic and presentation inside the same React component. And they may not know why it's important to separate these two – they just want to make it work. </p>
<p>But later, they'll find that they need to make changes to the file and doing so becomes a humungous task. Then they'll have to re-work things to separate these two parts.</p>
<p>This comes from not knowing about the separation of concerns and the presentation and container components pattern. That's why I'm going to teach you about them so you can mitigate this problem early in your project's development lifecycle.</p>
<p>In this article, we are going to dive into container and presentational components and briefly touch on the concept of separation of concerns.</p>
<p>Without further ado, let's get started!</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><a class="post-section-overview" href="#heading-what-is-the-separation-of-concerns">What is the separation of concerns?</a></li>
<li><a class="post-section-overview" href="#heading-what-are-container-and-presentational-components">What are presentation and container components?</a></li>
<li><a class="post-section-overview" href="#heading-why-do-we-need-these-components">Why do we need these components?</a></li>
<li><a class="post-section-overview" href="#heading-presentation-and-container-component-example">Presentation and container component example</a></li>
<li><a class="post-section-overview" href="#heading-how-to-replace-container-components-with-react-hooks">How to replace container components with React hooks</a></li>
<li><a class="post-section-overview" href="#heading-summary">Summary</a></li>
</ul>
<h2 id="heading-what-is-the-separation-of-concerns">What is the Separation of Concerns?</h2>
<p>Separation of concerns is a concept that is widely used in programming. It states that logic that performs different actions should not be groupled or combined together. </p>
<p>For example, what we discussed in the introduction section violates the separation of concerns, because we placed the logic of fetching the data and presenting the data in the same component. </p>
<p>To solve this and to adhere to the separation of concerns, we should separate these two pieces of logic – that is, fetching data and presenting it on the UI – into two different components. </p>
<p>This is were the container and presentation component pattern will help us solve this issue. In the following sections, we are going to dive deep into this pattern.</p>
<h2 id="heading-what-are-container-and-presentational-components">What are Container and Presentational Components?</h2>
<p>To achieve a separation of concerns we have two types of components:</p>
<ul>
<li>Container components</li>
<li>Presentational components</li>
</ul>
<h3 id="heading-container-components">Container components</h3>
<p>These are the components that provide, create, or hold data for the children components. </p>
<p>The only job of a container component is to handle data. It does not consist of any UI of its own. Rather, it consists of presentational components as its children that uses this data. </p>
<p>A simple example would be a component named <code>FetchUserContainer</code> that consists of some logic that fetches all the users.</p>
<h3 id="heading-presentational-components">Presentational components</h3>
<p>These are the components whose primary responsibility is to present the data on the UI. They take in the data from the container components. </p>
<p>These components are stateless unless they need their own state for rendering the UI. They do not alter the data that they receive.</p>
<p>An example of this would be a <code>UserList</code> component that displays all the users.</p>
<h2 id="heading-why-do-we-need-these-components">Why Do We Need These Components?</h2>
<p>To understand this, let's take a simple example. We want to display a list of posts that we fetch from the <a target="_blank" href="https://jsonplaceholder.typicode.com/">JSON placeholder API</a>. Here is the code for the same:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { useEffect, useState } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;

<span class="hljs-keyword">interface</span> Post {
  userId: <span class="hljs-built_in">number</span>;
  id: <span class="hljs-built_in">number</span>;
  title: <span class="hljs-built_in">string</span>;
  body: <span class="hljs-built_in">string</span>;
}

<span class="hljs-comment">/**
 * An example of how we shouldn't combine the logic and presentation of data.
 */</span>
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">DisplayPosts</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [posts, setPosts] = useState&lt;Post[] | <span class="hljs-literal">null</span>&gt;(<span class="hljs-literal">null</span>);
  <span class="hljs-keyword">const</span> [isLoading, setIsLoading] = useState&lt;<span class="hljs-built_in">Boolean</span>&gt;(<span class="hljs-literal">false</span>);
  <span class="hljs-keyword">const</span> [error, setError] = useState&lt;unknown&gt;();

<span class="hljs-comment">// Logic</span>
  useEffect(<span class="hljs-function">() =&gt;</span> {
    (<span class="hljs-keyword">async</span> () =&gt; {
      <span class="hljs-keyword">try</span> {
        setIsLoading(<span class="hljs-literal">true</span>);
        <span class="hljs-keyword">const</span> resp = <span class="hljs-keyword">await</span> fetch(<span class="hljs-string">"https://jsonplaceholder.typicode.com/posts"</span>);
        <span class="hljs-keyword">const</span> data = <span class="hljs-keyword">await</span> resp.json();
        setPosts(data);
        setIsLoading(<span class="hljs-literal">false</span>);
      } <span class="hljs-keyword">catch</span> (err) {
        setError(err);
        setIsLoading(<span class="hljs-literal">false</span>);
      }
    })();
  }, []);

<span class="hljs-comment">// Presentation</span>
  <span class="hljs-keyword">return</span> isLoading ? (
    &lt;span&gt;Loading... &lt;/span&gt;
  ) : posts ? (
    &lt;ul&gt;
      {posts.map(<span class="hljs-function">(<span class="hljs-params">post: Post</span>) =&gt;</span> (
        &lt;li key={<span class="hljs-string">`item-<span class="hljs-subst">${post.id}</span>`</span>}&gt;
          &lt;span&gt;{post.title}&lt;/span&gt;
        &lt;/li&gt;
      ))}
    &lt;/ul&gt;
  ) : (
    &lt;span&gt;{<span class="hljs-built_in">JSON</span>.stringify(error)}&lt;/span&gt;
  );
}
</code></pre>
<p>Here is what this component does:</p>
<ul>
<li>It has 3 state variables: <code>posts</code>, <code>isLoading</code>, and <code>error</code>.</li>
<li>We have a <code>useEffect</code> hook that consists of the business logic. Here we are fetching the data from the API: <code>[https://jsonplaceholder.typicode.com/posts](https://jsonplaceholder.typicode.com/posts)</code> with the <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch">fetch API</a>.</li>
<li>We make sure that when the data is fetched, we store it in the <code>posts</code> state variable using <code>setPosts</code>.</li>
<li>We also make sure that we toggle the <code>isLoading</code> and <code>error</code> values during the respective scenarios.</li>
<li>We put this entire logic inside an async IIFE.</li>
<li>Finally, we return the posts in the form of an unordered list and map through all the posts that we fetched earlier.</li>
</ul>
<p>The problem with the above is that the logic of fetching the data and displaying the data is coded into a single component. We can say that the component is now tightly coupled with the logic. This is the exact thing that we don’t want.</p>
<p>Below are some reasons as to why we require container and presentational components:</p>
<ul>
<li>They help us create components that are loosely coupled</li>
<li>They help us maintain separation of concerns</li>
<li>Code refactoring becomes much easier.</li>
<li>Code becomes more organized and maintainable</li>
<li>It makes testing much easier.</li>
</ul>
<h2 id="heading-presentation-and-container-component-example">Presentation and Container Component Example</h2>
<p>Ok, enough talk – let’s get things working by starting off with a simple example. We are going to use the same example as above – fetching the data from a JSON placeholder API.</p>
<p>Let's understand the file structure here: </p>
<ul>
<li>Our container component will be <code>PostContainer</code></li>
<li>We will be having two presentation components:<ul>
<li><code>Posts</code>: A component that has an unordered list.</li>
<li><code>SinglePost</code>: A component that renders a list tag. This will render each element of the list.</li>
</ul>
</li>
</ul>
<p>Note: We are going to store all the above components in a separate folder named <code>components</code>.</p>
<p>Now that we know which things go where, let's start off with the container component: <code>PostContainer</code>. Copy-paste the below code into the <code>components/PostContainer.tsx</code> file</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { useEffect, useState } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
<span class="hljs-keyword">import</span> { ISinglePost } <span class="hljs-keyword">from</span> <span class="hljs-string">"../Definitions"</span>;
<span class="hljs-keyword">import</span> Posts <span class="hljs-keyword">from</span> <span class="hljs-string">"./Posts"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">PostContainer</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [posts, setPosts] = useState&lt;ISinglePost[] | <span class="hljs-literal">null</span>&gt;(<span class="hljs-literal">null</span>);
  <span class="hljs-keyword">const</span> [isLoading, setIsLoading] = useState&lt;<span class="hljs-built_in">Boolean</span>&gt;(<span class="hljs-literal">false</span>);
  <span class="hljs-keyword">const</span> [error, setError] = useState&lt;unknown&gt;();

  useEffect(<span class="hljs-function">() =&gt;</span> {
    (<span class="hljs-keyword">async</span> () =&gt; {
      <span class="hljs-keyword">try</span> {
        setIsLoading(<span class="hljs-literal">true</span>);
        <span class="hljs-keyword">const</span> resp = <span class="hljs-keyword">await</span> fetch(<span class="hljs-string">"https://jsonplaceholder.typicode.com/posts"</span>);
        <span class="hljs-keyword">const</span> data = <span class="hljs-keyword">await</span> resp.json();
        setPosts(data.filter(<span class="hljs-function">(<span class="hljs-params">post: ISinglePost</span>) =&gt;</span> post.userId === <span class="hljs-number">1</span>));
        setIsLoading(<span class="hljs-literal">false</span>);
      } <span class="hljs-keyword">catch</span> (err) {
        setError(err);
        setIsLoading(<span class="hljs-literal">false</span>);
      }
    })();
  }, []);

  <span class="hljs-keyword">return</span> isLoading ? (
    &lt;span&gt;Loading... &lt;/span&gt;
  ) : posts ? (
    &lt;Posts posts={posts} /&gt;
  ) : (
    &lt;span&gt;{<span class="hljs-built_in">JSON</span>.stringify(error)}&lt;/span&gt;
  );
}
</code></pre>
<p>From the example we saw in the previous section of this article, the above code just contains the logic of fetching the data. This logic is present in the <code>useEffect</code> hook. Here this container component passes this data to the <code>Posts</code> presentational component.</p>
<p>Let's have a look at the <code>Posts</code> presentational component. Copy-paste the below code in the <code>components/Posts.tsx</code> file:</p>
<pre><code class="lang-typescript"><span class="hljs-comment">/**
 * A presentational component
 */</span>

<span class="hljs-keyword">import</span> { ISinglePost } <span class="hljs-keyword">from</span> <span class="hljs-string">"../Definitions"</span>;
<span class="hljs-keyword">import</span> SinglePost <span class="hljs-keyword">from</span> <span class="hljs-string">"./SinglePost"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Posts</span>(<span class="hljs-params">props: { posts: ISinglePost[] }</span>) </span>{
  <span class="hljs-keyword">return</span> (
    &lt;ul
      style={{
        display: <span class="hljs-string">"flex"</span>,
        flexDirection: <span class="hljs-string">"column"</span>,
        alignItems: <span class="hljs-string">"center"</span>
      }}
    &gt;
      {props.posts.map(<span class="hljs-function">(<span class="hljs-params">post: ISinglePost</span>) =&gt;</span> (
        &lt;SinglePost {...post} /&gt;
      ))}
    &lt;/ul&gt;
  );
}
</code></pre>
<p>As you can see, this is a simple file that consists of a <code>ul</code> tag – an unordered list. This component then maps over the <code>posts</code> that are being passed as props. We pass each to the <code>SinglePost</code> component.</p>
<p>There is another presentational component that renders the list tag, that is the <code>li</code> tag. It displays the title and the body of the post. Copy-paste the below code in the <code>components/SinglePost.tsx</code> file:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { ISinglePost } <span class="hljs-keyword">from</span> <span class="hljs-string">"../Definitions"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">SinglePost</span>(<span class="hljs-params">props: ISinglePost</span>) </span>{
  <span class="hljs-keyword">const</span> { userId, id, title, body } = props;
  <span class="hljs-keyword">return</span> (
    &lt;li key={<span class="hljs-string">`item-<span class="hljs-subst">${userId}</span>-<span class="hljs-subst">${id}</span>`</span>} style={{ width: <span class="hljs-number">400</span> }}&gt;
      &lt;h4&gt;
        &lt;strong&gt;{title}&lt;/strong&gt;
      &lt;/h4&gt;
      &lt;span&gt;{body}&lt;/span&gt;
    &lt;/li&gt;
  );
}
</code></pre>
<p>These presentational components, as you can see, just display the data on the screen. That’s all. They don’t do anything else. Since they are just displaying the data here, they will also have their own styling.</p>
<p>Now that we have setup the components, let's look back on what we have achieved here:</p>
<ul>
<li>The concept of separation of concerns is not violated in this example.</li>
<li>Writing unit tests for each component becomes easier.</li>
<li>Code maintainability and readability are much better. Thus our codebase has become much more organized.</li>
</ul>
<p>We have achieved what we wanted here, but we can further enhance this pattern with the help of hooks.</p>
<h2 id="heading-how-to-replace-container-components-with-react-hooks">How to Replace Container Components with React Hooks</h2>
<p>Since <strong>React 16.8.0</strong>, it has become so much easier to build and develop components with the help of functional components and hooks. </p>
<p>We are going to leverage these capabilities here and replace the container component with a hook.</p>
<p>Copy-paste the below code in the <code>hooks/usePosts.ts</code> file:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { useEffect, useState } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
<span class="hljs-keyword">import</span> { ISinglePost } <span class="hljs-keyword">from</span> <span class="hljs-string">"../Definitions"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">usePosts</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [posts, setPosts] = useState&lt;ISinglePost[] | <span class="hljs-literal">null</span>&gt;(<span class="hljs-literal">null</span>);
  <span class="hljs-keyword">const</span> [isLoading, setIsLoading] = useState&lt;<span class="hljs-built_in">Boolean</span>&gt;(<span class="hljs-literal">false</span>);
  <span class="hljs-keyword">const</span> [error, setError] = useState&lt;unknown&gt;();

  useEffect(<span class="hljs-function">() =&gt;</span> {
    (<span class="hljs-keyword">async</span> () =&gt; {
      <span class="hljs-keyword">try</span> {
        setIsLoading(<span class="hljs-literal">true</span>);
        <span class="hljs-keyword">const</span> resp = <span class="hljs-keyword">await</span> fetch(<span class="hljs-string">"https://jsonplaceholder.typicode.com/posts"</span>);
        <span class="hljs-keyword">const</span> data = <span class="hljs-keyword">await</span> resp.json();
        setPosts(data.filter(<span class="hljs-function">(<span class="hljs-params">post: ISinglePost</span>) =&gt;</span> post.userId === <span class="hljs-number">1</span>));
        setIsLoading(<span class="hljs-literal">false</span>);
      } <span class="hljs-keyword">catch</span> (err) {
        setError(err);
        setIsLoading(<span class="hljs-literal">false</span>);
      }
    })();
  }, []);

  <span class="hljs-keyword">return</span> {
    isLoading,
    posts,
    error
  };
}
</code></pre>
<p>Here we have,</p>
<ul>
<li>Extracted logic that was present in the <code>PostContainer</code> component into a hook.</li>
<li>This hook will return an object that contains the <code>isLoading</code>, <code>posts</code>, and <code>error</code> values.</li>
</ul>
<p>Now we can simply remove the container component <code>PostContainer</code>. Then, rather than passing the container's data to the presentational components as a prop, we can directly use this hook inside the <code>Posts</code> presentational component.</p>
<p>Make the following edits to the <code>Posts</code> component:</p>
<pre><code class="lang-typescript"><span class="hljs-comment">/**
 * A presentational component
 */</span>

<span class="hljs-keyword">import</span> { ISinglePost } <span class="hljs-keyword">from</span> <span class="hljs-string">"../Definitions"</span>;
<span class="hljs-keyword">import</span> usePosts <span class="hljs-keyword">from</span> <span class="hljs-string">"../hooks/usePosts"</span>;
<span class="hljs-keyword">import</span> SinglePost <span class="hljs-keyword">from</span> <span class="hljs-string">"./SinglePost"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Posts</span>(<span class="hljs-params">props: { posts: ISinglePost[] }</span>) </span>{
  <span class="hljs-keyword">const</span> { isLoading, posts, error } = usePosts();

  <span class="hljs-keyword">return</span> (
    &lt;ul
      style={{
        display: <span class="hljs-string">"flex"</span>,
        flexDirection: <span class="hljs-string">"column"</span>,
        alignItems: <span class="hljs-string">"center"</span>
      }}
    &gt;
      {isLoading ? (
        &lt;span&gt;Loading...&lt;/span&gt;
      ) : posts ? (
        posts.map(<span class="hljs-function">(<span class="hljs-params">post: ISinglePost</span>) =&gt;</span> &lt;SinglePost {...post} /&gt;)
      ) : (
        &lt;span&gt;{<span class="hljs-built_in">JSON</span>.stringify(error)}&lt;/span&gt;
      )}
    &lt;/ul&gt;
  );
}
</code></pre>
<p>By making use of hooks we have eliminated an extra layer of component that was present on top of these presentational components. </p>
<p>With hooks, we achieved the same results as that of the container/presentational components pattern.</p>
<h2 id="heading-summary">Summary</h2>
<p>So in this article, we learned about:</p>
<ul>
<li>Separation of concerns</li>
<li>Container and presentational components</li>
<li>Why we need these components</li>
<li>How hooks can replace container components</li>
</ul>
<p>For further reading I would highly recommend going through the <a target="_blank" href="https://tanstack.com/table/v8/">react-table:</a>. This library extensively uses hooks and it has great examples.</p>
<p>You can find the entire code for this article in this <a target="_blank" href="https://codesandbox.io/s/container-presentation-pattern-lm1osl?file=/src/components/PostContainer.tsx">codesandbox</a>.</p>
<p>Thanks for reading!</p>
<p>Follow me on <a target="_blank" href="https://twitter.com/keurplkar">Twitter</a>, <a target="_blank" href="https://github.com/keyurparalkar">GitHub</a>, and <a target="_blank" href="https://www.linkedin.com/in/keyur-paralkar-494415107/">LinkedIn</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How To Use Axios With React: The Definitive Guide (2021) ]]>
                </title>
                <description>
                    <![CDATA[ In this guide, you will see exactly how to use Axios.js with React using tons of real-world examples featuring React hooks.  You'll see why you should use Axios as a data fetching library, how to set it up with React, and perform every type of HTTP r... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-use-axios-with-react/</link>
                <guid isPermaLink="false">66d0378f871ae63f179f6baf</guid>
                
                    <category>
                        <![CDATA[ axios ]]>
                    </category>
                
                    <category>
                        <![CDATA[ hooks ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                    <category>
                        <![CDATA[ react hooks ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Reed ]]>
                </dc:creator>
                <pubDate>Tue, 13 Jul 2021 07:36:28 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2021/07/how-to-use-axios-with-react.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In this guide, you will see exactly how to use Axios.js with React using tons of real-world examples featuring React hooks. </p>
<p>You'll see why you should use Axios as a data fetching library, how to set it up with React, and perform every type of HTTP request with it.</p>
<p>Then we'll touch on more advanced features like creating an Axios instance for reusability, using async-await with Axios for simplicity, and how to use Axios as a custom hook.</p>
<p>Let's dive right in!</p>
<h3 id="heading-want-your-own-copy"><strong>Want Your Own Copy?‬ 📄</strong></h3>
<p><strong><a target="_blank" href="https://reedbarger.com/resources/react-axios-2021">Click here to download the cheatsheet in PDF format</a></strong> (it takes 5 seconds).</p>
<p>It includes all of the essential information here as a convenient PDF guide.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><a class="post-section-overview" href="#heading-what-is-axios">What is Axios?</a></li>
<li><a class="post-section-overview" href="#heading-why-use-axios-in-react">Why Use Axios in React?</a></li>
<li><a class="post-section-overview" href="#heading-how-to-set-up-axios-with-react">How to Set Up Axios with React</a></li>
<li><a class="post-section-overview" href="#heading-how-to-make-a-get-request">How to Make a GET Request (Retrieve Data)</a></li>
<li><a class="post-section-overview" href="#heading-how-to-make-a-post-request">How to Make a POST Request (Create Data)</a></li>
<li><a class="post-section-overview" href="#heading-how-to-make-a-put-request">How to Make a PUT Request (Update Data)</a></li>
<li><a class="post-section-overview" href="#heading-how-to-make-a-delete-request">How to Make a DELETE Request (Delete Data)</a></li>
<li><a class="post-section-overview" href="#heading-how-to-handle-errors-with-axios">How to Handle Errors with Axios</a></li>
<li><a class="post-section-overview" href="#heading-how-to-create-an-axios-instance">How to Create an Axios Instance</a></li>
<li><a class="post-section-overview" href="#heading-how-to-use-the-async-await-syntax-with-axios">How to Use the Async-Await Syntax with Axios</a></li>
<li><a class="post-section-overview" href="#heading-how-to-create-a-custom-useaxios-hook">How to Create a Custom <code>useAxios</code> Hook</a></li>
</ul>
<h2 id="heading-what-is-axios">What is Axios?</h2>
<p>Axios is an HTTP client library that allows you to make requests to a given endpoint:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/07/Screen-Shot-2021-07-12-at-1.14.41-PM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>This could be an external API or your own backend Node.js server, for example.</p>
<p>By making a request, you expect your API to perform an operation according to the request you made.</p>
<p>For example, if you make a GET request, you expect to get back data to display in your application.</p>
<h2 id="heading-why-use-axios-in-react">Why Use Axios in React</h2>
<p>There are a number of different libraries you can use to make these requests, so why choose Axios? </p>
<p>Here are <strong>five reasons</strong> why you should use Axios as your client to make HTTP requests: </p>
<ol>
<li>It has good defaults to work with JSON data. Unlike alternatives such as the Fetch API, you often don't need to set your headers. Or perform tedious tasks like converting your request body to a JSON string.</li>
<li>Axios has function names that match any HTTP methods. To perform a GET request, you use the <code>.get()</code> method.</li>
<li>Axios does more with less code. Unlike the Fetch API, you only need one <code>.then()</code> callback to access your requested JSON data.</li>
<li>Axios has better error handling. Axios throws 400 and 500 range errors for you. Unlike the Fetch API, where you have to check the status code and throw the error yourself. </li>
<li>Axios can be used on the server as well as the client. If you are writing a Node.js application, be aware that Axios can also be used in an environment separate from the browser. </li>
</ol>
<h2 id="heading-how-to-set-up-axios-with-react">How to Set Up Axios with React</h2>
<p>Using Axios with React is a very simple process. You need three things:</p>
<ol>
<li>An existing React project</li>
<li>To install Axios with npm/yarn</li>
<li>An API endpoint for making requests</li>
</ol>
<p>The quickest way to create a new React application is by going to <a target="_blank" href="https://react.new">react.new</a>.</p>
<p>If you have an existing React project, you just need to install Axios with npm (or any other package manager):</p>
<pre><code class="lang-bash">npm install axios
</code></pre>
<p>In this guide, you'll use the JSON Placeholder API to get and change post data.</p>
<p>Here is a list of all the different routes you can make requests to, along with the appropriate HTTP method for each:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/07/Screen-Shot-2021-07-10-at-12.21.28-PM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Here is a quick example of all of the operations you'll be performing with Axios and your API endpoint — retrieving, creating, updating, and deleting posts:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/07/axios-react.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-how-to-make-a-get-request">How to Make a GET Request</h2>
<p>To fetch data or retrieve it, make a GET request.</p>
<p>First, you're going to make a request for individual posts. If you look at the endpoint, you are getting the first post from the <code>/posts</code> endpoint:</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> axios <span class="hljs-keyword">from</span> <span class="hljs-string">"axios"</span>;
<span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;

<span class="hljs-keyword">const</span> baseURL = <span class="hljs-string">"https://jsonplaceholder.typicode.com/posts/1"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [post, setPost] = React.useState(<span class="hljs-literal">null</span>);

  React.useEffect(<span class="hljs-function">() =&gt;</span> {
    axios.get(baseURL).then(<span class="hljs-function">(<span class="hljs-params">response</span>) =&gt;</span> {
      setPost(response.data);
    });
  }, []);

  <span class="hljs-keyword">if</span> (!post) <span class="hljs-keyword">return</span> <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">h1</span>&gt;</span>{post.title}<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>{post.body}<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>
<p>To perform this request when the component mounts, you use the <code>useEffect</code> hook. This involves importing Axios, using the <code>.get()</code> method to make a GET request to your endpoint, and using a <code>.then()</code> callback to get back all of the response data.</p>
<p>The response is returned as an object. The data (which is in this case a post with <code>id</code>, <code>title</code>, and <code>body</code> properties) is put in a piece of state called <code>post</code> which is displayed in the component. </p>
<p>Note that you can always find the requested data from the <code>.data</code> property in the response.</p>
<h2 id="heading-how-to-make-a-post-request">How to Make a POST Request</h2>
<p>To create new data, make a POST request. </p>
<p>According to the API, this needs to be performed on the <code>/posts</code> endpoint. If you look at the code below, you'll see that there's a button to create a post:</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> axios <span class="hljs-keyword">from</span> <span class="hljs-string">"axios"</span>;
<span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;

<span class="hljs-keyword">const</span> baseURL = <span class="hljs-string">"https://jsonplaceholder.typicode.com/posts"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [post, setPost] = React.useState(<span class="hljs-literal">null</span>);

  React.useEffect(<span class="hljs-function">() =&gt;</span> {
    axios.get(<span class="hljs-string">`<span class="hljs-subst">${baseURL}</span>/1`</span>).then(<span class="hljs-function">(<span class="hljs-params">response</span>) =&gt;</span> {
      setPost(response.data);
    });
  }, []);

  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">createPost</span>(<span class="hljs-params"></span>) </span>{
    axios
      .post(baseURL, {
        <span class="hljs-attr">title</span>: <span class="hljs-string">"Hello World!"</span>,
        <span class="hljs-attr">body</span>: <span class="hljs-string">"This is a new post."</span>
      })
      .then(<span class="hljs-function">(<span class="hljs-params">response</span>) =&gt;</span> {
        setPost(response.data);
      });
  }

  <span class="hljs-keyword">if</span> (!post) <span class="hljs-keyword">return</span> <span class="hljs-string">"No post!"</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">h1</span>&gt;</span>{post.title}<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>{post.body}<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">{createPost}</span>&gt;</span>Create Post<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>When you click on the button, it calls the <code>createPost</code> function.</p>
<p>To make that POST request with Axios, you use the <code>.post()</code> method. As the second argument, you include an object property that specifies what you want the new post to be.</p>
<p>Once again, use a <code>.then()</code> callback to get back the response data and replace the first post you got with the new post you requested.</p>
<p>This is very similar to the <code>.get()</code> method, but the new resource you want to create is provided as the second argument after the API endpoint.</p>
<h2 id="heading-how-to-make-a-put-request">How to Make a PUT Request</h2>
<p>To update a given resource, make a PUT request.</p>
<p>In this case, you'll update the first post.</p>
<p>To do so, you'll once again create a button. But this time, the button will call a function to update a post:</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> axios <span class="hljs-keyword">from</span> <span class="hljs-string">"axios"</span>;
<span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;

<span class="hljs-keyword">const</span> baseURL = <span class="hljs-string">"https://jsonplaceholder.typicode.com/posts"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [post, setPost] = React.useState(<span class="hljs-literal">null</span>);

  React.useEffect(<span class="hljs-function">() =&gt;</span> {
    axios.get(<span class="hljs-string">`<span class="hljs-subst">${baseURL}</span>/1`</span>).then(<span class="hljs-function">(<span class="hljs-params">response</span>) =&gt;</span> {
      setPost(response.data);
    });
  }, []);

  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">updatePost</span>(<span class="hljs-params"></span>) </span>{
    axios
      .put(<span class="hljs-string">`<span class="hljs-subst">${baseURL}</span>/1`</span>, {
        <span class="hljs-attr">title</span>: <span class="hljs-string">"Hello World!"</span>,
        <span class="hljs-attr">body</span>: <span class="hljs-string">"This is an updated post."</span>
      })
      .then(<span class="hljs-function">(<span class="hljs-params">response</span>) =&gt;</span> {
        setPost(response.data);
      });
  }

  <span class="hljs-keyword">if</span> (!post) <span class="hljs-keyword">return</span> <span class="hljs-string">"No post!"</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">h1</span>&gt;</span>{post.title}<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>{post.body}<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">{updatePost}</span>&gt;</span>Update Post<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>In the code above, you use the PUT method from Axios. And like with the POST method, you include the properties that you want to be in the updated resource.</p>
<p>Again, using the <code>.then()</code> callback, you update the JSX with the data that is returned.</p>
<h2 id="heading-how-to-make-a-delete-request">How to Make a DELETE Request</h2>
<p>Finally, to delete a resource, use the DELETE method.</p>
<p>As an example, we'll delete the first post.</p>
<p>Note that you do not need a second argument whatsoever to perform this request:</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> axios <span class="hljs-keyword">from</span> <span class="hljs-string">"axios"</span>;
<span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;

<span class="hljs-keyword">const</span> baseURL = <span class="hljs-string">"https://jsonplaceholder.typicode.com/posts"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [post, setPost] = React.useState(<span class="hljs-literal">null</span>);

  React.useEffect(<span class="hljs-function">() =&gt;</span> {
    axios.get(<span class="hljs-string">`<span class="hljs-subst">${baseURL}</span>/1`</span>).then(<span class="hljs-function">(<span class="hljs-params">response</span>) =&gt;</span> {
      setPost(response.data);
    });
  }, []);

  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">deletePost</span>(<span class="hljs-params"></span>) </span>{
    axios
      .delete(<span class="hljs-string">`<span class="hljs-subst">${baseURL}</span>/1`</span>)
      .then(<span class="hljs-function">() =&gt;</span> {
        alert(<span class="hljs-string">"Post deleted!"</span>);
        setPost(<span class="hljs-literal">null</span>)
      });
  }

  <span class="hljs-keyword">if</span> (!post) <span class="hljs-keyword">return</span> <span class="hljs-string">"No post!"</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">h1</span>&gt;</span>{post.title}<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>{post.body}<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">{deletePost}</span>&gt;</span>Delete Post<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>In most cases, you do not need the data that's returned from the <code>.delete()</code> method.</p>
<p>But in the code above, the <code>.then()</code> callback is still used to ensure that your request is successfully resolved.</p>
<p>In the code above, after a post is deleted, the user is alerted that it was deleted successfully. Then, the post data is cleared out of the state by setting it to its initial value of <code>null</code>.</p>
<p>Also, once a post is deleted, the text "No post" is shown immediately after the alert message.</p>
<h2 id="heading-how-to-handle-errors-with-axios">How to Handle Errors with Axios</h2>
<p>What about handling errors with Axios? </p>
<p>What if there's an error while making a request? For example, you might pass along the wrong data, make a request to the wrong endpoint, or have a network error.</p>
<p>To simulate an error, you'll send a request to an API endpoint that doesn't exist: <code>/posts/asdf</code>.</p>
<p>This request will return a <code>404</code> status code:</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> axios <span class="hljs-keyword">from</span> <span class="hljs-string">"axios"</span>;
<span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;

<span class="hljs-keyword">const</span> baseURL = <span class="hljs-string">"https://jsonplaceholder.typicode.com/posts"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [post, setPost] = React.useState(<span class="hljs-literal">null</span>);
  <span class="hljs-keyword">const</span> [error, setError] = React.useState(<span class="hljs-literal">null</span>);

  React.useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-comment">// invalid url will trigger an 404 error</span>
    axios.get(<span class="hljs-string">`<span class="hljs-subst">${baseURL}</span>/asdf`</span>).then(<span class="hljs-function">(<span class="hljs-params">response</span>) =&gt;</span> {
      setPost(response.data);
    }).catch(<span class="hljs-function"><span class="hljs-params">error</span> =&gt;</span> {
      setError(error);
    });
  }, []);

  <span class="hljs-keyword">if</span> (error) <span class="hljs-keyword">return</span> <span class="hljs-string">`Error: <span class="hljs-subst">${error.message}</span>`</span>;
  <span class="hljs-keyword">if</span> (!post) <span class="hljs-keyword">return</span> <span class="hljs-string">"No post!"</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">h1</span>&gt;</span>{post.title}<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>{post.body}<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>
<p>In this case, instead of executing the <code>.then()</code> callback, Axios will throw an error and run the <code>.catch()</code> callback function.</p>
<p>In this function, we are taking the error data and putting it in state to alert our user about the error. So if we have an error, we will display that error message.</p>
<p>In this function, the error data is put in state and used to alert users about the error. So if there's an error, an error message is displayed.</p>
<p>When you run this code code, you'll see the text, "Error: Request failed with status code 404".</p>
<h2 id="heading-how-to-create-an-axios-instance">How to Create an Axios Instance</h2>
<p>If you look at the previous examples, you'll see that there's a <code>baseURL</code> that you use as part of the endpoint for Axios to perform these requests.</p>
<p>However, it gets a bit tedious to keep writing that <code>baseURL</code> for every single request. Couldn't you just have Axios remember what <code>baseURL</code> you're using, since it always involves a similar endpoint? </p>
<p>In fact, you can. If you create an instance with the <code>.create()</code> method, Axios will remember that <code>baseURL</code>, plus other values you might want to specify for every request, including headers: </p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> axios <span class="hljs-keyword">from</span> <span class="hljs-string">"axios"</span>;
<span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;

<span class="hljs-keyword">const</span> client = axios.create({
  <span class="hljs-attr">baseURL</span>: <span class="hljs-string">"https://jsonplaceholder.typicode.com/posts"</span> 
});

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [post, setPost] = React.useState(<span class="hljs-literal">null</span>);

  React.useEffect(<span class="hljs-function">() =&gt;</span> {
    client.get(<span class="hljs-string">"/1"</span>).then(<span class="hljs-function">(<span class="hljs-params">response</span>) =&gt;</span> {
      setPost(response.data);
    });
  }, []);

  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">deletePost</span>(<span class="hljs-params"></span>) </span>{
    client
      .delete(<span class="hljs-string">"/1"</span>)
      .then(<span class="hljs-function">() =&gt;</span> {
        alert(<span class="hljs-string">"Post deleted!"</span>);
        setPost(<span class="hljs-literal">null</span>)
      });
  }

  <span class="hljs-keyword">if</span> (!post) <span class="hljs-keyword">return</span> <span class="hljs-string">"No post!"</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">h1</span>&gt;</span>{post.title}<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>{post.body}<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">{deletePost}</span>&gt;</span>Delete Post<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>The one property in the config object above is <code>baseURL</code>, to which you pass the endpoint.</p>
<p>The <code>.create()</code> function returns a newly created instance, which in this case is called <code>client</code>.</p>
<p>Then in the future, you can use all the same methods as you did before, but you don't have to include the <code>baseURL</code> as the first argument anymore. You just have to reference the specific route you want, for example, <code>/</code>, <code>/1</code>, and so on.</p>
<h2 id="heading-how-to-use-the-async-await-syntax-with-axios">How to Use the Async-Await Syntax with Axios</h2>
<p>A big benefit to using promises in JavaScript (including React applications) is the async-await syntax.</p>
<p>Async-await allows you to write much cleaner code without <code>then</code> and <code>catch</code> callback functions. Plus, code with async-await looks a lot like synchronous code, and is easier to understand.</p>
<p>But how do you use the async-await syntax with Axios?</p>
<p>In the example below, posts are fetched and there's still a button to delete that post:</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> axios <span class="hljs-keyword">from</span> <span class="hljs-string">"axios"</span>;
<span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;

<span class="hljs-keyword">const</span> client = axios.create({
  <span class="hljs-attr">baseURL</span>: <span class="hljs-string">"https://jsonplaceholder.typicode.com/posts"</span> 
});

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [post, setPost] = React.useState(<span class="hljs-literal">null</span>);

  React.useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getPost</span>(<span class="hljs-params"></span>) </span>{
      <span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> client.get(<span class="hljs-string">"/1"</span>);
      setPost(response.data);
    }
    getPost();
  }, []);

  <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">deletePost</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">await</span> client.delete(<span class="hljs-string">"/1"</span>);
    alert(<span class="hljs-string">"Post deleted!"</span>);
    setPost(<span class="hljs-literal">null</span>);
  }

  <span class="hljs-keyword">if</span> (!post) <span class="hljs-keyword">return</span> <span class="hljs-string">"No post!"</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">h1</span>&gt;</span>{post.title}<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>{post.body}<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">{deletePost}</span>&gt;</span>Delete Post<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>However in <code>useEffect</code>, there's an <code>async</code> function called <code>getPost</code>.</p>
<p>Making it <code>async</code> allows you to use the <code>await</code> keword to resolve the GET request and set that data in state on the next line without the <code>.then()</code> callback. </p>
<p>Note that the <code>getPost</code> function is called immediately after being created.</p>
<p>Additionally, the <code>deletePost</code> function is now <code>async</code>, which is a requirement to use the <code>await</code> keyword which resolves the promise it returns (every Axios method returns a promise to resolve).</p>
<p>After using the <code>await</code> keyword with the DELETE request, the user is alerted that the post was deleted, and the post is set to <code>null</code>.</p>
<p>As you can see, async-await cleans up the code a great deal, and you can use it with Axios very easily.</p>
<h2 id="heading-how-to-create-a-custom-useaxios-hook">How to Create a Custom <code>useAxios</code> Hook</h2>
<p>Async-await is a great way to simplify your code, but you can take this a step further.</p>
<p>Instead of using <code>useEffect</code> to fetch data when the component mounts, you could create your own custom hook with Axios to perform the same operation as a reusable function.</p>
<p>While you can make this custom hook yourself, there's a very good library that gives you a custom <code>useAxios</code> hook called use-axios-client.</p>
<p>First, install the package:</p>
<pre><code>npm install use-axios-client
</code></pre><p>To use the hook itself, import <code>useAxios</code> from use-axios-client at the top of the component. </p>
<p>Because you no longer need <code>useEffect</code>, you can remove the React import:</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> { useAxios } <span class="hljs-keyword">from</span> <span class="hljs-string">"use-axios-client"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> { data, error, loading } = useAxios({
    <span class="hljs-attr">url</span>: <span class="hljs-string">"https://jsonplaceholder.typicode.com/posts/1"</span>
  });

  <span class="hljs-keyword">if</span> (loading || !data) <span class="hljs-keyword">return</span> <span class="hljs-string">"Loading..."</span>;
  <span class="hljs-keyword">if</span> (error) <span class="hljs-keyword">return</span> <span class="hljs-string">"Error!"</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">h1</span>&gt;</span>{data.title}<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>{data.body}<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>
<p>Now you can call <code>useAxios</code> at the top of the app component, pass in the URL you want to make a request to, and the hook returns an object with all the values you need to handle the different states: <code>loading</code>, <code>error</code> and the resolved <code>data</code>.</p>
<p>In the process of performing this request, the value <code>loading</code> will be true. If there's an error, you'll want to display that error state. Otherwise, if you have the returned data, you can display it in the UI.</p>
<p>The benefit of custom hooks like this is that it really cuts down on code and simplifies it overall. </p>
<p>If you're looking for even simpler data fetching with Axios, try out a custom <code>useAxios</code> hook like this one.</p>
<h2 id="heading-whats-next">What's Next?</h2>
<p>Congratulations! You now know how to use one of the most powerful HTTP client libraries to power your React applications. </p>
<p>I hope you got a lot out of this guide.</p>
<p><a target="_blank" href="https://reedbarger.com/resources/react-axios-2021">Remember that you can download this guide as a PDF cheatsheet to keep for future reference.</a></p>
<h2 id="heading-become-a-professional-react-developer">Become a Professional React Developer</h2>
<p>React is hard. You shouldn't have to figure it out yourself.</p>
<p>I've put everything I know about React into a single course, to help you reach your goals in record time:</p>
<p><a target="_blank" href="https://www.thereactbootcamp.com"><strong>Introducing: The React Bootcamp</strong></a></p>
<p><strong>It’s the one course I wish I had when I started learning React.</strong></p>
<p>Click below to try the React Bootcamp for yourself:</p>
<p><a target="_blank" href="https://www.thereactbootcamp.com"><img src="https://reedbarger.nyc3.digitaloceanspaces.com/reactbootcamp/react-bootcamp-cta-alt.png" alt="Click to join the React Bootcamp" width="600" height="400" loading="lazy"></a>
<em>Click to get started</em></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ React for Beginners: Complete React Cheatsheet for 2021 ]]>
                </title>
                <description>
                    <![CDATA[ Welcome to the React for Beginners guide. It's designed to teach you all the core React concepts that you need to know to start building React applications in 2021. I created this resource to give you the most complete and beginner-friendly path to l... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/react-for-beginners-cheatsheet/</link>
                <guid isPermaLink="false">66d037bd871ae63f179f6bbc</guid>
                
                    <category>
                        <![CDATA[ beginners guide ]]>
                    </category>
                
                    <category>
                        <![CDATA[ cheatsheet ]]>
                    </category>
                
                    <category>
                        <![CDATA[ hooks ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Reed ]]>
                </dc:creator>
                <pubDate>Fri, 14 May 2021 20:17:37 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2021/05/react-for-beginners-2021.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Welcome to the React for Beginners guide. It's designed to teach you all the core React concepts that you need to know to start building React applications in 2021.</p>
<p>I created this resource to give you the most complete and beginner-friendly path to learn React from the ground up.</p>
<p>By the end you will have a thorough understanding of tons of essential React concepts, including:</p>
<ul>
<li>The Why, What, and How of React</li>
<li>How to Easily Create React Apps</li>
<li>JSX and Basic Syntax</li>
<li>JSX Elements</li>
<li>Components and Props</li>
<li>Events in React</li>
<li>State and State Management</li>
<li>The Basics of React Hooks</li>
</ul>
<h3 id="heading-want-your-own-copy">Want Your Own Copy?‬ 📄</h3>
<p><strong><a target="_blank" href="https://reedbarger.com/resources/react-beginners-2021">Download the cheatsheet in PDF format here</a></strong> (it takes 5 seconds).</p>
<p>Here are some quick wins from grabbing the downloadable version:</p>
<ul>
<li>Quick reference guide to review however and whenever</li>
<li>Tons of copyable code snippets for easy reuse</li>
<li>Read this massive guide wherever suits you best. On the train, at your desk, standing in line... anywhere.</li>
</ul>
<p>There's a ton of great stuff to cover, so let's get started.</p>
<h2 id="heading-react-basics">React Basics</h2>
<h3 id="heading-what-is-react-really">What is React, really?</h3>
<p>React is officially defined as a "JavaScript library for creating user interfaces," but what does that really mean?</p>
<p>React is a library, made in JavaScript and which we code in JavaScript, to build great applications that run on the web.</p>
<h3 id="heading-what-do-i-need-to-know-to-learn-react">What do I need to know to learn React?</h3>
<p>In other words, you do need to have a basic understanding of JavaScript to become a solid React programmer?</p>
<p>The most basic JavaScript concepts you should be familiar with are variables, basic data types, conditionals, array methods, functions, and ES modules.</p>
<p>How do I learn all of these JavaScript skills? <a target="_blank" href="https://reactbootcamp.com/javascript-skills-for-react-2021/">Check out the comprehensive guide</a> to learn all of the JavaScript you need for React.</p>
<h3 id="heading-if-react-was-made-in-javascript-why-dont-we-just-use-javascript">If React was made in JavaScript, why don't we just use JavaScript?</h3>
<p>React was written in JavaScript, which was built from the ground up for the express purpose of building web applications and gives us tools to do so.</p>
<p>JavaScript is a 20+ year old language which was created for adding small bits of behavior to the browser through scripts and was not designed for creating complete applications.</p>
<p>In other words, while JavaScript was used to create React, they were created for very different purposes.</p>
<h3 id="heading-can-i-use-javascript-in-react-applications">Can I use JavaScript in React applications?</h3>
<p>Yes! You can include any valid JavaScript code within your React applications.</p>
<p>You can use any browser or window API, such as geolocation or the fetch API.</p>
<p>Also, since React (when it is compiled) runs in the browser, you can perform common JavaScript actions like DOM querying and manipulation.</p>
<h2 id="heading-how-to-create-react-apps">How to Create React Apps</h2>
<h3 id="heading-three-different-ways-to-create-a-react-application">Three different ways to create a React application</h3>
<ol>
<li>Putting React in an HTML file with external scripts </li>
<li>Using an in-browser React environment like CodeSandbox</li>
<li>Creating a React app on your computer using a tool like Create React App</li>
</ol>
<h3 id="heading-what-is-the-best-way-to-create-a-react-app">What is the best way to create a React app?</h3>
<p>Which is the best approach for you? The best way to create your application depends on what you want to do with it.</p>
<p>If you want to create a complete web application that you want to ultimately push to the web, it is best to create that React application on your computer using a tool like Create React App.</p>
<p>If you are interested in creating React apps on your computer, <a target="_blank" href="https://reactbootcamp.com/create-react-app-10-steps/">check out the complete guide to using Create React App</a>.</p>
<p>The easiest and most beginner-friendly way to create and build React apps for learning and prototyping is to use a tool like CodeSandbox. You can create a new React app in seconds by going to <a target="_blank" href="https://react.new">react.new</a>!</p>
<h2 id="heading-jsx-elements">JSX Elements</h2>
<h3 id="heading-jsx-is-a-powerful-tool-for-structuring-applications">JSX is a powerful tool for structuring applications</h3>
<p><strong>JSX</strong> is meant to make creating user interfaces with JavaScript applications easier.</p>
<p>It borrows its syntax from the most widely used programming language: HTML. As a result, JSX is a powerful tool to structure our applications.</p>
<p>The code example below is the most basic example of a React element which displays the text "Hello World":</p>
<pre><code class="lang-js">&lt;div&gt;Hello React!&lt;/div&gt;
</code></pre>
<p>Note that to be displayed in the browser, React elements need to be <strong>rendered</strong> (using <code>ReactDOM.render()</code>).</p>
<h3 id="heading-how-jsx-is-different-from-html">How JSX is different from HTML</h3>
<p>We can write valid HTML elements in JSX, but what differs slightly is the way some attributes are written.</p>
<p>Attributes that consist of multiple words are written in the camel-case syntax (like <code>className</code>) and have different names than standard HTML (<code>class</code>).</p>
<pre><code class="lang-js">&lt;div id=<span class="hljs-string">"header"</span>&gt;
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">h1</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"title"</span>&gt;</span>Hello React!<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span></span>
&lt;/div&gt;
</code></pre>
<p>JSX has this different way of writing attributes because it is actually made using JavaScript functions (more on this later).</p>
<h3 id="heading-jsx-must-have-a-trailing-slash-if-it-is-made-of-one-tag">JSX must have a trailing slash if it is made of one tag</h3>
<p>Unlike standard HTML, elements like <code>input</code>, <code>img</code>, or <code>br</code> must close with a trailing forward slash for it to be valid JSX.</p>
<pre><code class="lang-js">&lt;input type=<span class="hljs-string">"email"</span> /&gt; <span class="hljs-comment">// &lt;input type="email"&gt; is a syntax error</span>
</code></pre>
<h3 id="heading-jsx-elements-with-two-tags-must-have-a-closing-tag">JSX elements with two tags must have a closing tag</h3>
<p>Elements that should have two tags, such as <code>div</code>, <code>main</code> or <code>button</code>, must have their closing, second tag in JSX, otherwise it will result in a syntax error.</p>
<pre><code class="lang-js">&lt;button&gt;Click me&lt;<span class="hljs-regexp">/button&gt; /</span><span class="hljs-regexp">/ &lt;button&gt; or &lt;/</span>button&gt; is a syntax error
</code></pre>
<h3 id="heading-how-jsx-elements-are-styled">How JSX elements are styled</h3>
<p>Inline styles are written differently as well as compared to plain HTML.</p>
<ul>
<li>Inline styles must not be included as a string, but within an object.</li>
<li>Once again, the style properties that we use must be written in the camel-case style.</li>
</ul>
<pre><code class="lang-js">&lt;h1 style={{ <span class="hljs-attr">color</span>: <span class="hljs-string">"blue"</span>, <span class="hljs-attr">fontSize</span>: <span class="hljs-number">22</span>, <span class="hljs-attr">padding</span>: <span class="hljs-string">"0.5em 1em"</span> }}&gt;
  Hello React!
&lt;/h1&gt;;
</code></pre>
<p>Style properties that accept pixel values (like width, height, padding, margin, etc), can use integers instead of strings. For example, <code>fontSize: 22</code> instead of <code>fontSize: "22px"</code>.</p>
<h3 id="heading-jsx-can-be-conditionally-displayed">JSX can be conditionally displayed</h3>
<p>New React developers may be wondering how it is beneficial that React can use JavaScript code.</p>
<p>One simple example if that to conditionally hide or display JSX content, we can use any valid JavaScript conditional, like an if statement or switch statement.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> isAuthUser = <span class="hljs-literal">true</span>;

<span class="hljs-keyword">if</span> (isAuthUser) {
  <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>Hello user!<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>   
} <span class="hljs-keyword">else</span> {
  <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span>&gt;</span>Login<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span>
}
</code></pre>
<p>Where are we returning this code? Within a React component, which we will cover in a later section.</p>
<h3 id="heading-jsx-cannot-be-understood-by-the-browser">JSX cannot be understood by the browser</h3>
<p>As mentioned above, JSX is not HTML, but is composed of JavaScript functions.</p>
<p>In fact, writing <code>&lt;div&gt;Hello React&lt;/div&gt;</code> in JSX is just a more convenient and understandable way of writing code like the following:</p>
<pre><code class="lang-js">React.createElement(<span class="hljs-string">"div"</span>, <span class="hljs-literal">null</span>, <span class="hljs-string">"Hello React!"</span>)
</code></pre>
<p>Both pieces of code will have the same output of "Hello React".</p>
<p>To write JSX and have the browser understand this different syntax, we must use a <strong>transpiler</strong> to convert JSX to these function calls.</p>
<p>The most common transpiler is called <strong>Babel.</strong></p>
<h2 id="heading-react-components">React Components</h2>
<h3 id="heading-what-are-react-components">What are React components?</h3>
<p>Instead of just rendering one or another set of JSX elements, we can include them within React <strong>components</strong>.</p>
<p>Components are created using what looks like a normal JavaScript function, but it's different in that it returns JSX elements.</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Greeting</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>Hello React!<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>;   
}
</code></pre>
<h3 id="heading-why-use-react-components">Why use React components?</h3>
<p>React components allow us to create more complex logic and structures within our React application than we would with JSX elements alone.</p>
<p>Think of React components as our custom React elements that have their own functionality.</p>
<p>As we know, functions allow us to create our own functionality and reuse it where we like across our application.</p>
<p>Components are reusable wherever we like across our app and as many times as we like.</p>
<h3 id="heading-components-are-not-normal-javascript-functions">Components are not normal JavaScript functions</h3>
<p>How would we render or display the returned JSX from the component above?</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
<span class="hljs-keyword">import</span> ReactDOM <span class="hljs-keyword">from</span> <span class="hljs-string">'react-dom'</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Greeting</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>Hello React!<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>;   
}

ReactDOM.render(<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Greeting</span> /&gt;</span></span>, <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"root));</span>
</code></pre>
<p>We use the <code>React</code> import to parse the JSX and <code>ReactDOM</code> to render our component to a <strong>root element</strong> with the id of "root."</p>
<h3 id="heading-what-can-react-components-return">What can React components return?</h3>
<p>Components can return valid JSX elements, as well as strings, numbers, booleans, the value <code>null</code>, as well as arrays and fragments.</p>
<p>Why would we want to return <code>null</code>? It is common to return <code>null</code> if we want a component to display nothing.</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Greeting</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">if</span> (isAuthUser) {
    <span class="hljs-keyword">return</span> <span class="hljs-string">"Hello again!"</span>;   
  } <span class="hljs-keyword">else</span> {
    <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;
  }
}
</code></pre>
<p>Another rule is that JSX elements must be wrapped in one parent element. Multiple sibling elements cannot be returned.</p>
<p>If you need to return multiple elements, but don't need to add another element to the DOM (usually for a conditional), you can use a special React component called a fragment.</p>
<p>Fragments can be written as <code>&lt;&gt;&lt;/&gt;</code> or when you import React into your file, with <code>&lt;React.Fragment&gt;&lt;/React.Fragment&gt;</code>.</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Greeting</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> isAuthUser = <span class="hljs-literal">true</span>;  

  <span class="hljs-keyword">if</span> (isAuthUser) {
    <span class="hljs-keyword">return</span> (
      <span class="xml"><span class="hljs-tag">&lt;&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Hello again!<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">button</span>&gt;</span>Logout<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
      <span class="hljs-tag">&lt;/&gt;</span></span>
    );
  } <span class="hljs-keyword">else</span> {
    <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;
  }
}
</code></pre>
<p>Note that when attempting to return a number of JSX elements that are spread over multiple lines, we can return it all using a set of parentheses () as you see in the example above.</p>
<h3 id="heading-components-can-return-other-components">Components can return other components</h3>
<p>The most important thing components can return is other components.</p>
<p>Below is a basic example of a React application contained with in a component called <code>App</code> that returns multiple components:</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
<span class="hljs-keyword">import</span> ReactDOM <span class="hljs-keyword">from</span> <span class="hljs-string">'react-dom'</span>;

<span class="hljs-keyword">import</span> Layout <span class="hljs-keyword">from</span> <span class="hljs-string">'./components/Layout'</span>;
<span class="hljs-keyword">import</span> Navbar <span class="hljs-keyword">from</span> <span class="hljs-string">'./components/Navbar'</span>;
<span class="hljs-keyword">import</span> Aside <span class="hljs-keyword">from</span> <span class="hljs-string">'./components/Aside'</span>;
<span class="hljs-keyword">import</span> Main <span class="hljs-keyword">from</span> <span class="hljs-string">'./components/Main'</span>;
<span class="hljs-keyword">import</span> Footer <span class="hljs-keyword">from</span> <span class="hljs-string">'./components/Footer'</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Layout</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">Navbar</span> /&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">Main</span> /&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">Aside</span> /&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">Footer</span> /&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">Layout</span>&gt;</span></span>
  );
}

ReactDOM.render(<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">App</span> /&gt;</span></span>, <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'root'</span>));
</code></pre>
<p>This is powerful because we are using the customization of components to describe what they are (that is, the Layout) and their function in our application. This tells us how they should be used just by looking at their name.</p>
<p>Additionally, we are using the power of JSX to compose these components. In other words, to use the HTML-like syntax of JSX to structure them in an immediately understandable way (like the Navbar is at the top of the app, the Footer at the bottom, and so on).</p>
<h3 id="heading-javascript-can-be-used-in-jsx-using-curly-braces">JavaScript can be used in JSX using curly braces</h3>
<p>Just as we can use JavaScript variables within our components, we can use them directly within our JSX as well.</p>
<p>There are a few core rules to using dynamic values within JSX, though:</p>
<ul>
<li>JSX can accept any primitive values (strings, booleans, numbers), but it will not accept plain objects.</li>
<li>JSX can also include expressions that resolve to these values.</li>
</ul>
<p>For example, conditionals can be included within JSX using the ternary operator, since it resolves to a value.</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Greeting</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> isAuthUser = <span class="hljs-literal">true</span>;  

  <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>{isAuthUser ? "Hello!" : null}<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>;
}
</code></pre>
<h2 id="heading-props-in-react">Props in React</h2>
<h3 id="heading-components-can-be-passed-values-using-props">Components can be passed values using props</h3>
<p>Data passed to components in JavaScript are called <strong>props</strong>.</p>
<p>Props look identical to attributes on plain JSX/HTML elements, but you can access their values within the component itself.</p>
<p>Props are available in parameters of the component to which they are passed. Props are always included as properties of an object.</p>
<pre><code class="lang-js">ReactDOM.render(
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Greeting</span> <span class="hljs-attr">username</span>=<span class="hljs-string">"John!"</span> /&gt;</span></span>,
  <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"root"</span>)
);

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Greeting</span>(<span class="hljs-params">props</span>) </span>{
  <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Hello {props.username}<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span></span>;
}
</code></pre>
<h3 id="heading-props-cannot-be-directly-changed">Props cannot be directly changed</h3>
<p>Props must never be directly changed within the child component.</p>
<p>Another way to say this is that props should never be <strong>mutated</strong>, since props are a plain JavaScript object</p>
<pre><code class="lang-js"><span class="hljs-comment">// We cannot modify the props object:</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Header</span>(<span class="hljs-params">props</span>) </span>{
  props.username = <span class="hljs-string">"Doug"</span>;

  <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Hello {props.username}<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span></span>;
}
</code></pre>
<p>Components are considered pure functions. That is, for every input, we should be able to expect the same output. This means we cannot mutate the props object, only read from it.</p>
<h3 id="heading-special-props-the-children-prop">Special props: the children prop</h3>
<p>The <strong>children</strong> prop is useful if we want to pass elements / components as props to other components</p>
<p>The children prop is especially useful for when you want the same component (such as a Layout component) to wrap all other components.</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Layout</span>(<span class="hljs-params">props</span>) </span>{
  <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"container"</span>&gt;</span>{props.children}<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>;
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">IndexPage</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Layout</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">Header</span> /&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">Hero</span> /&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">Footer</span> /&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">Layout</span>&gt;</span></span>
  );
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">AboutPage</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Layout</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">About</span> /&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">Footer</span> /&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">Layout</span>&gt;</span></span>
  );
}
</code></pre>
<p>The benefit of this pattern is that all styles applied to the Layout component will be shared with its child components.</p>
<h2 id="heading-lists-and-keys-in-react">Lists and Keys in React</h2>
<h3 id="heading-how-to-iterate-over-arrays-in-jsx-using-map">How to iterate over arrays in JSX using map</h3>
<p>How do we displays lists in JSX using array data? We use the <strong><code>.map()</code></strong> function to convert lists of data (arrays) into lists of elements.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> people = [<span class="hljs-string">"John"</span>, <span class="hljs-string">"Bob"</span>, <span class="hljs-string">"Fred"</span>];
<span class="hljs-keyword">const</span> peopleList = people.map(<span class="hljs-function">(<span class="hljs-params">person</span>) =&gt;</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>{person}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span></span>);
</code></pre>
<p>You can use <code>.map()</code> for components as well as plain JSX elements.</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> people = [<span class="hljs-string">"John"</span>, <span class="hljs-string">"Bob"</span>, <span class="hljs-string">"Fred"</span>];

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span>
      {people.map((person) =&gt; (
        <span class="hljs-tag">&lt;<span class="hljs-name">Person</span> <span class="hljs-attr">name</span>=<span class="hljs-string">{person}</span> /&gt;</span>
      ))}
    <span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span></span>
  );
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Person</span>(<span class="hljs-params">{ name }</span>) </span>{
  <span class="hljs-comment">// we access the 'name' prop directly using object destructuring</span>
  <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>This person's name is: {name}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span></span>;
}
</code></pre>
<h3 id="heading-the-importance-of-keys-in-lists">The importance of keys in lists</h3>
<p>Each React element within a list of elements needs a special <strong>key prop</strong>.</p>
<p>Keys are essential for React to be able to keep track of each element that is being iterated over with the <code>.map()</code> function.</p>
<p>React uses keys to performantly update individual elements when their data changes (instead of re-rendering the entire list).</p>
<p>Keys need to have unique values to be able to identify each of them according to their key value.</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> people = [
    { <span class="hljs-attr">id</span>: <span class="hljs-string">"Ksy7py"</span>, <span class="hljs-attr">name</span>: <span class="hljs-string">"John"</span> },
    { <span class="hljs-attr">id</span>: <span class="hljs-string">"6eAdl9"</span>, <span class="hljs-attr">name</span>: <span class="hljs-string">"Bob"</span> },
    { <span class="hljs-attr">id</span>: <span class="hljs-string">"6eAdl9"</span>, <span class="hljs-attr">name</span>: <span class="hljs-string">"Fred"</span> },
  ];

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span>
      {people.map((person) =&gt; (
        <span class="hljs-tag">&lt;<span class="hljs-name">Person</span> <span class="hljs-attr">key</span>=<span class="hljs-string">{person.id}</span> <span class="hljs-attr">name</span>=<span class="hljs-string">{person.name}</span> /&gt;</span>
      ))}
    <span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span></span>
  );
}
</code></pre>
<h2 id="heading-state-and-managing-data-in-react">State and Managing Data in React</h2>
<h3 id="heading-what-is-state-in-react">What is state in React?</h3>
<p><strong>State</strong> is a concept that refers to how data in our application changes over time. </p>
<p>The significance of state in React is that it is a way to talk about our data separately from the user interface (what the user sees).</p>
<p>We talk about state management, because we need an effective way to keep track of and update data across our components as our user interacts with it.</p>
<p>To change our application from static HTML elements to a dynamic one that the user can interact with, we need state.</p>
<h3 id="heading-examples-of-how-to-use-state-in-react">Examples of how to use state in React</h3>
<p>We need to manage state often when our user wants to interact with our application. </p>
<p>When a user types into a form, we keep track of the form state in that component.</p>
<p>When we fetch data from an API to display to the user (such as posts in a blog), we need to save that data in state.</p>
<p>When we want to change data that a component is receiving from props, we use state to change it instead of mutating the props object.</p>
<h3 id="heading-introduction-to-react-hooks-with-usestate">Introduction to React hooks with useState</h3>
<p>The way to "create" state is React within a particular component is with the <code>useState</code> hook.</p>
<p>What is a hook? It is very much like a JavaScript function, but can only be used in a React function component at the top of the component.</p>
<p>We use hooks to "hook into" certain features, and <code>useState</code> gives us the ability to create and manage state.</p>
<p><code>useState</code> is an example of a core React hook that comes directly from the React library: <code>React.useState</code>.</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React <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">Greeting</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> state = React.useState(<span class="hljs-string">"Hello React"</span>);  

  <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>{state[0]}<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span> <span class="hljs-comment">// displays "Hello React"</span>
}
</code></pre>
<p>How does <code>useState</code> work? Like a normal function, we can pass it a starting value (like "Hello React").</p>
<p>What is returned from useState is an array. To get access to the state variable and its value, we can use the first value in that array: <code>state[0]</code>.</p>
<p>There is a way to improve how we write this, however. We can use array destructuring to get direct access to this state variable and call it what we like, such as <code>title</code>.</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React <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">Greeting</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [title] = React.useState(<span class="hljs-string">"Hello React"</span>);  

  <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>{title}<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span> <span class="hljs-comment">// displays "Hello React"</span>
}
</code></pre>
<p>What if we want to allow our user to update the greeting they see? If we include a form, a user can type in a new value. However, we need a way to update the initial value of our title.</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React <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">Greeting</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [title] = React.useState(<span class="hljs-string">"Hello React"</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">h1</span>&gt;</span>{title}<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"Update title"</span> /&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}
</code></pre>
<p>We can do so with the help of the second element in the array that useState returns. It is a setter function, to which we can pass whatever value we want the new state to be.</p>
<p>In our case, we want to get the value that is typed into the input when a user is in the process of typing. We can get it with the help of React events.</p>
<h3 id="heading-what-are-events-in-react">What are events in React?</h3>
<p>Events are ways to get data about a certain action that a user has performed in our app.</p>
<p>The most common props used to handle events are <code>onClick</code> (for click events), <code>onChange</code> (when a user types into an input), and <code>onSubmit</code> (when a form is submitted).</p>
<p>Event data is given to us by connecting a function to each of these props listed (there are many more to choose from than these three).</p>
<p>To get data about the event when our input is changed, we can add <code>onChange</code> on input and connect it to a function that will handle the event. This function will be called <code>handleInputChange</code>:</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React <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">Greeting</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [title] = React.useState(<span class="hljs-string">"Hello React"</span>);

  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handleInputChange</span>(<span class="hljs-params">event</span>) </span>{
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"input changed!"</span>, event);
  }

  <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">h1</span>&gt;</span>{title}<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"Update title"</span> <span class="hljs-attr">onChange</span>=<span class="hljs-string">{handleInputChange}</span> /&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}
</code></pre>
<p>Note that in the code above, a new event will be logged to the browser's console whenever the user types into the input</p>
<p>Event data is provided to us as an object with many properties which are dependent upon the type of event.</p>
<h3 id="heading-how-to-update-state-in-react-with-usestate">How to update state in React with useState</h3>
<p>To update state with useState, we can use the second element that useState returns to us in its array.</p>
<p>This element is a function that will allow us to update the value of the state variable (the first element). Whatever we pass to this setter function when we call it will be put in state.</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React <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">Greeting</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [title, setTitle] = React.useState(<span class="hljs-string">"Hello React"</span>);

  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handleInputChange</span>(<span class="hljs-params">event</span>) </span>{
    setTitle(event.target.value);
  }

  <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">h1</span>&gt;</span>{title}<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"Update title"</span> <span class="hljs-attr">onChange</span>=<span class="hljs-string">{handleInputChange}</span> /&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}
</code></pre>
<p>Using the code above, whatever the user types into the input (the text comes from <code>event.target.value</code>) will be put in state using <code>setTitle</code> and displayed within the <code>h1</code> element.</p>
<p>What is special about state and why it must be managed with a dedicated hook like useState is because a state update (such as when we call <code>setTitle</code>) causes a re-render.</p>
<p>A re-render is when a certain component renders or is displayed again based off the new data. If our components weren't re-rendered when data changed, we would never see the app's appearance change at all!</p>
<h2 id="heading-whats-next"><strong>What's Next</strong></h2>
<p>I hope you got a lot of out this guide.</p>
<p>If you want a copy of this cheatsheet to keep for learning purposes, you can <a target="_blank" href="https://reedbarger.com/resources/react-beginners-2021">download a complete PDF version of this cheatsheet here</a>.</p>
<p>Once you have finished with this guide, there are many things you can learn to advance your skills to the next level, including:</p>
<ul>
<li><a target="_blank" href="https://reactbootcamp.com/how-to-code-react-hooks/">How to write custom React hooks</a></li>
<li><a target="_blank" href="https://reactbootcamp.com/react-props-cheatsheet/">The complete guide to React props</a></li>
<li><a target="_blank" href="https://reactbootcamp.com/fetch-data-in-react/">How to fetch data in React from front to back</a></li>
<li><a target="_blank" href="https://reactbootcamp.com/react-app-node-backend/">How to build fullstack apps in React with Node</a></li>
<li><a target="_blank" href="https://reactbootcamp.com/what-to-know-about-react-state/">Learn more about React state</a></li>
<li><a target="_blank" href="https://reactbootcamp.com/react-router-cheatsheet/">How to add routing to your React app with React Router</a></li>
<li><a target="_blank" href="https://reactbootcamp.com/react-cheatsheet-2021/">Learn every part of React with the advanced React cheatsheet</a></li>
</ul>
<h2 id="heading-become-a-professional-react-developer">Become a Professional React Developer</h2>
<p>React is hard. You shouldn't have to figure it out yourself.</p>
<p>I've put everything I know about React into a single course, to help you reach your goals in record time:</p>
<p><a target="_blank" href="https://www.thereactbootcamp.com"><strong>Introducing: The React Bootcamp</strong></a></p>
<p><strong>It’s the one course I wish I had when I started learning React.</strong></p>
<p>Click below to try the React Bootcamp for yourself:</p>
<p><a target="_blank" href="https://www.thereactbootcamp.com"><img src="https://reedbarger.nyc3.digitaloceanspaces.com/reactbootcamp/react-bootcamp-cta-alt.png" alt="Click to join the React Bootcamp" width="600" height="400" loading="lazy"></a>
<em>Click to get started</em></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Use Debounce and Throttle in React and Abstract them into Hooks ]]>
                </title>
                <description>
                    <![CDATA[ By Divyanshu Maithani Hooks are a brilliant addition to React. They simplify a lot of logic that previously had to be split up into different lifecycles with class components.  They do, however, require a different mental model, especially for first-... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/debounce-and-throttle-in-react-with-hooks/</link>
                <guid isPermaLink="false">66d45e3f182810487e0ce149</guid>
                
                    <category>
                        <![CDATA[ hooks ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Wed, 15 Jul 2020 04:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2020/07/og-image.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Divyanshu Maithani</p>
<p><a target="_blank" href="https://reactjs.org/docs/hooks-intro.html">Hooks</a> are a brilliant addition to React. They simplify a lot of logic that previously had to be split up into different lifecycles with <code>class</code> components. </p>
<p>They do, however, require a <em>different</em> mental model, <a target="_blank" href="https://overreacted.io/making-setinterval-declarative-with-react-hooks/">especially for first-timers</a>.</p>
<blockquote>
<p>I also recorded a short <a target="_blank" href="https://www.youtube.com/playlist?list=PLMV09mSPNaQlN92-1Dkz5NDlNgGQJEo75">video series</a> on this article which you may find helpful.</p>
</blockquote>
<h2 id="heading-debounce-and-throttle">Debounce and throttle</h2>
<p>There are a ton of blog posts written about debounce and throttle so I won't be diving into how to write your own debounce and throttle. For brevity, consider <a target="_blank" href="https://lodash.com/docs/4.17.15#debounce"><code>debounce</code></a> and <a target="_blank" href="https://lodash.com/docs/4.17.15#throttle"><code>throttle</code></a> from Lodash.</p>
<p>If you need a quick refresher, both accept a (callback) function and a <em>delay</em> in milliseconds (say <code>x</code>) and then both return another function with some special behavior:</p>
<ul>
<li><code>debounce</code>: returns a function that can be called any number of times (possibly in quick successions) but will only invoke the callback <strong>after waiting</strong> for <code>x</code> ms from the last call.</li>
<li><code>throttle</code>: returns a function that can be called any number of times (possibly in quick succession) but will only invoke the callback at most <strong>once</strong> every <code>x</code> ms.</li>
</ul>
<h2 id="heading-usecase">Usecase</h2>
<p>We have a minimal blog editor (here's the <a target="_blank" href="https://github.com/wtjs/react-debounce-throttle-hooks/">GitHub repo</a>) and we would like to save the blog post to the database 1 second after the user stops typing.</p>
<blockquote>
<p>You may also refer to <a target="_blank" href="https://codesandbox.io/s/github/wtjs/react-debounce-throttle-hooks">this Codesandbox</a> if you wish to see the final version of the code.</p>
</blockquote>
<p>A minimal version of our editor looks like this:</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React, { useState } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
<span class="hljs-keyword">import</span> debounce <span class="hljs-keyword">from</span> <span class="hljs-string">'lodash.debounce'</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">const</span> [value, setValue] = useState(<span class="hljs-string">''</span>);
    <span class="hljs-keyword">const</span> [dbValue, saveToDb] = useState(<span class="hljs-string">''</span>); <span class="hljs-comment">// would be an API call normally</span>

    <span class="hljs-keyword">const</span> handleChange = <span class="hljs-function"><span class="hljs-params">event</span> =&gt;</span> {
        setValue(event.target.value);
    };

    <span class="hljs-keyword">return</span> (
        <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">main</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Blog<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">textarea</span> <span class="hljs-attr">value</span>=<span class="hljs-string">{value}</span> <span class="hljs-attr">onChange</span>=<span class="hljs-string">{handleChange}</span> <span class="hljs-attr">rows</span>=<span class="hljs-string">{5}</span> <span class="hljs-attr">cols</span>=<span class="hljs-string">{50}</span> /&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">section</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"panels"</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
                    <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>Editor (Client)<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
                    {value}
                <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
                    <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>Saved (DB)<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
                    {dbValue}
                <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">section</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">main</span>&gt;</span></span>
    );
}
</code></pre>
<p>Here, <code>saveToDb</code> would actually be an API call to the backend. To keep things simple, I'm saving it in state and then rendering as <code>dbValue</code>. </p>
<p>Since we only want to perform this save operation once user has stopped typing (after 1 second), this should be <em>debounced</em>.</p>
<p><a target="_blank" href="https://github.com/wtjs/react-debounce-throttle-hooks/tree/starter">Here's</a> the starter code repo and branch.</p>
<h2 id="heading-creating-a-debounced-function">Creating a debounced function</h2>
<p>First of all, we need a debounced function that wraps the call to <code>saveToDb</code>:</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React, { useState } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
<span class="hljs-keyword">import</span> debounce <span class="hljs-keyword">from</span> <span class="hljs-string">'lodash.debounce'</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">const</span> [value, setValue] = useState(<span class="hljs-string">''</span>);
    <span class="hljs-keyword">const</span> [dbValue, saveToDb] = useState(<span class="hljs-string">''</span>); <span class="hljs-comment">// would be an API call normally</span>

    <span class="hljs-keyword">const</span> handleChange = <span class="hljs-function"><span class="hljs-params">event</span> =&gt;</span> {
        <span class="hljs-keyword">const</span> { <span class="hljs-attr">value</span>: nextValue } = event.target;
        setValue(nextValue);
        <span class="hljs-comment">// highlight-starts</span>
        <span class="hljs-keyword">const</span> debouncedSave = debounce(<span class="hljs-function">() =&gt;</span> saveToDb(nextValue), <span class="hljs-number">1000</span>);
        debouncedSave();
        <span class="hljs-comment">// highlight-ends</span>
    };

    <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">main</span>&gt;</span>{/* Same as before */}<span class="hljs-tag">&lt;/<span class="hljs-name">main</span>&gt;</span></span>;
}
</code></pre>
<p>But, this doesn't actually work because the function <code>debouncedSave</code> is created fresh on each <code>handleChange</code> call. This will end up debouncing each keystroke rather than debouncing the entire input value.</p>
<h2 id="heading-usecallback">useCallback</h2>
<p><a target="_blank" href="https://reactjs.org/docs/hooks-reference.html#usecallback"><code>useCallback</code></a> is commonly used for performance optimizations when passing callbacks to child components. But we can use its constraint of memoizing a callback function to ensure the <code>debouncedSave</code> references the same debounced function across renders.</p>
<blockquote>
<p>I also wrote <a target="_blank" href="https://www.freecodecamp.org/news/understanding-memoize-in-javascript-51d07d19430e/">this article</a> here on freeCodeCamp if you wish to understand the basics of memoization.</p>
</blockquote>
<p>This works as expected:</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React, { useState, useCallback } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
<span class="hljs-keyword">import</span> debounce <span class="hljs-keyword">from</span> <span class="hljs-string">'lodash.debounce'</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">const</span> [value, setValue] = useState(<span class="hljs-string">''</span>);
    <span class="hljs-keyword">const</span> [dbValue, saveToDb] = useState(<span class="hljs-string">''</span>); <span class="hljs-comment">// would be an API call normally</span>

    <span class="hljs-comment">// highlight-starts</span>
    <span class="hljs-keyword">const</span> debouncedSave = useCallback(
        debounce(<span class="hljs-function"><span class="hljs-params">nextValue</span> =&gt;</span> saveToDb(nextValue), <span class="hljs-number">1000</span>),
        [], <span class="hljs-comment">// will be created only once initially</span>
    );
    <span class="hljs-comment">// highlight-ends</span>

    <span class="hljs-keyword">const</span> handleChange = <span class="hljs-function"><span class="hljs-params">event</span> =&gt;</span> {
        <span class="hljs-keyword">const</span> { <span class="hljs-attr">value</span>: nextValue } = event.target;
        setValue(nextValue);
        <span class="hljs-comment">// Even though handleChange is created on each render and executed</span>
        <span class="hljs-comment">// it references the same debouncedSave that was created initially</span>
        debouncedSave(nextValue);
    };

    <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">main</span>&gt;</span>{/* Same as before */}<span class="hljs-tag">&lt;/<span class="hljs-name">main</span>&gt;</span></span>;
}
</code></pre>
<h2 id="heading-useref">useRef</h2>
<p><a target="_blank" href="https://reactjs.org/docs/hooks-reference.html#useref"><code>useRef</code></a> gives us a mutable object whose <code>current</code> property refers to the passed initial value. If we don't change it manually, the value will persist for the entire lifetime of the component. </p>
<p>This is similar to class instance properties (i.e. defining methods and properties on <code>this</code>).</p>
<p>This also works as expected:</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React, { useState, useRef } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
<span class="hljs-keyword">import</span> debounce <span class="hljs-keyword">from</span> <span class="hljs-string">'lodash.debounce'</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">const</span> [value, setValue] = useState(<span class="hljs-string">''</span>);
    <span class="hljs-keyword">const</span> [dbValue, saveToDb] = useState(<span class="hljs-string">''</span>); <span class="hljs-comment">// would be an API call normally</span>

    <span class="hljs-comment">// This remains same across renders</span>
    <span class="hljs-comment">// highlight-starts</span>
    <span class="hljs-keyword">const</span> debouncedSave = useRef(debounce(<span class="hljs-function"><span class="hljs-params">nextValue</span> =&gt;</span> saveToDb(nextValue), <span class="hljs-number">1000</span>))
        .current;
    <span class="hljs-comment">// highlight-ends</span>

    <span class="hljs-keyword">const</span> handleChange = <span class="hljs-function"><span class="hljs-params">event</span> =&gt;</span> {
        <span class="hljs-keyword">const</span> { <span class="hljs-attr">value</span>: nextValue } = event.target;
        setValue(nextValue);
        <span class="hljs-comment">// Even though handleChange is created on each render and executed</span>
        <span class="hljs-comment">// it references the same debouncedSave that was created initially</span>
        debouncedSave(nextValue);
    };

    <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">main</span>&gt;</span>{/* Same as before */}<span class="hljs-tag">&lt;/<span class="hljs-name">main</span>&gt;</span></span>;
}
</code></pre>
<p>Continue reading on <a target="_blank" href="https://divyanshu013.dev/blog/react-debounce-throttle-hooks/">my blog</a> for how to abstract these concepts into custom hooks or check out the <a target="_blank" href="https://www.youtube.com/playlist?list=PLMV09mSPNaQlN92-1Dkz5NDlNgGQJEo75">video series</a>.</p>
<p>You may also follow me on <a target="_blank" href="https://twitter.com/divyanshu013">Twitter</a> to stay updated on my latest posts. I hope you found this post helpful. :)</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Create a Custom React Hook and Publish it to npm ]]>
                </title>
                <description>
                    <![CDATA[ Hooks are a handy addition to the React API that allow us to organize some of our logic and state in function components. How can we build a custom hook and share it with the rest of the world? What are hooks? Why are custom hooks cool? What are we ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-create-a-custom-react-hook-and-publish-it-to-npm/</link>
                <guid isPermaLink="false">66b8e34f682e4a25eed261a0</guid>
                
                    <category>
                        <![CDATA[ front end ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Front-end Development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ frontend ]]>
                    </category>
                
                    <category>
                        <![CDATA[ hooks ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ npm ]]>
                    </category>
                
                    <category>
                        <![CDATA[ npm scripts ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                    <category>
                        <![CDATA[ react hooks ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Yarn ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Colby Fayock ]]>
                </dc:creator>
                <pubDate>Tue, 14 Apr 2020 14:45:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/07/Custom-React-Hooks-Book-Cover--1-.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Hooks are a handy addition to the React API that allow us to organize some of our logic and state in function components. How can we build a custom hook and share it with the rest of the world?</p>
<ul>
<li><a class="post-section-overview" href="#heading-what-are-hooks">What are hooks?</a></li>
<li><a class="post-section-overview" href="#heading-why-are-custom-hooks-cool">Why are custom hooks cool?</a></li>
<li><a class="post-section-overview" href="#heading-what-are-we-going-to-make">What are we going to make?</a></li>
<li><a class="post-section-overview" href="#heading-step-0-naming-your-hook">Step 0: Naming your hook</a></li>
<li><a class="post-section-overview" href="#heading-step-1-setting-up-your-project">Step 1: Setting up your project</a></li>
<li><a class="post-section-overview" href="#heading-step-2-writing-your-new-react-hook">Step 2: Writing your new React Hook</a></li>
<li><a class="post-section-overview" href="#heading-step-3-using-your-react-hook-in-an-example">Step 3: Using your React hook in an example</a></li>
<li><a class="post-section-overview" href="#heading-step-4-compiling-your-react-hook-and-example">Step 4: Compiling your React hook and Example</a></li>
<li><a class="post-section-overview" href="#heading-step-5-publishing-your-react-hook-to-npm">Step 5: Publishing your React hook to npm</a></li>
<li><a class="post-section-overview" href="#heading-more-resources-about-hooks">More resources about hooks</a></li>
</ul>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/Q0xVnRanXVk" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<h2 id="heading-what-are-hooks">What are hooks?</h2>
<p>React <a target="_blank" href="https://reactjs.org/docs/hooks-intro.html">hooks</a> in simple terms are functions. When you include them in your component or within another hook, they allow you to make use of React internals and parts of the React lifecycle with native hooks like <code>useState</code> and <code>useEffect</code>.</p>
<p>I don’t plan on doing a deep dive about hooks, but you can <a target="_blank" href="https://www.freecodecamp.org/news/how-to-destructure-the-fundamentals-of-react-hooks-d13ff6ea6871/">check out a quick introduction</a> with an example of <code>useState</code> as well as <a target="_blank" href="https://reactjs.org/docs/hooks-intro.html">the intro from the React team</a>.</p>
<h2 id="heading-why-are-custom-hooks-cool">Why are custom hooks cool?</h2>
<p>The great thing about creating custom hooks is they allow you to abstract logic for your components making it easier to reuse across multiple components in your app.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/hook-example-use-counter-1.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Hook diagram example for useCounter</em></p>
<p>For instance, if you wanted to create a simple counter where you use React’s state to manage the current count. Instead of having the same <code>useState</code> hook in each component file, you can create that logic once in a <code>useCounter</code> hook, making it easier to maintain, extend, and squash bugs if they come up.</p>
<h2 id="heading-what-are-we-going-to-make">What are we going to make?</h2>
<p>For the purposes of this article, we’re going to keep it simple with a basic hook. Typically, you might use a hook because rather than a typical function, you use other native hooks that are required to be used within React function components. We’re going to stick with some basic input and output to keep things simple.</p>
<p>We’re going to recreate this custom <a target="_blank" href="https://github.com/colbyfayock/use-placecage">Placecage hook</a> I made, that allows you to easily generate image URLs that you can use as placeholder images.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/nic-cage-excited.gif" alt="Image" width="600" height="400" loading="lazy">
<em>Nic Cage excited</em></p>
<p>If you’re not familiar, <a target="_blank" href="https://www.placecage.com/">Placecage</a> is an API that allows you to generate pictures of Nic Cage as placeholder images for your website. Silly? Yes. Fun? Absolutely!</p>
<p>But if you’re not a fan of Nic's work, you can just as easily swap in the URL for <a target="_blank" href="https://placeholder.com/">Fill Murray</a> which uses pictures of Bill Murray or <a target="_blank" href="https://placeholder.com/">placeholder.com</a> which generates simple solid color background with text that shows the size of the image.</p>
<h2 id="heading-step-0-naming-your-hook">Step 0: Naming your hook</h2>
<p>Before we jump in to our actual code, our ultimate goal is to publish this hook. If that’s not your goal, you can skip this step, but for publishing, we’ll want to create a name for our hook.</p>
<p>In our case, our hook name will be <code>usePlaceCage</code>. Now with that in mind, we have 2 formats of our name — one in camelCase format and one in snake-case format.</p>
<ul>
<li><strong>camelCase:</strong> usePlaceCage</li>
<li><strong>snake-case:</strong> use-placecage</li>
</ul>
<p>The camelCase format will be used for the actual hook function, where the snake-case name will be used for the package name and some of the folders. When creating the name, keep in mind that the package name must be unique. If a package with the same name exists on <a target="_blank" href="https://www.npmjs.com/">npmjs.com</a> already, you won't be able to use it.</p>
<p>If you don’t already have a name, it's okay! You can just use your own name or something you can think of, it doesn’t really matter too much as really we're just trying to learn how to do this. If it were me for instance, I would use:</p>
<ul>
<li><strong>camelCase:</strong> useColbysCoolHook</li>
<li><strong>snake-case:</strong> use-colbyscoolhook</li>
</ul>
<p>But just to clarify, for the rest of our example, we’re going to stick with <code>usePlaceCage</code> and <code>use-placecage</code>.</p>
<h2 id="heading-step-1-setting-up-your-project">Step 1: Setting up your project</h2>
<p>Though you can set up your project however you’d like, we’re going to walk through building a new hook from <a target="_blank" href="https://github.com/colbyfayock/use-custom-hook">this template</a> I created.</p>
<p>The hope here, is that we can take out some of the painful bits of the process and immediately get productive with our custom hook. Don’t worry though, I’ll explain what’s going on along the way.</p>
<p>The requirements here are <a target="_blank" href="https://git-scm.com/">git</a> and <a target="_blank" href="https://yarnpkg.com/">yarn</a> as it helps provide tools that make it easy to scaffold this template, such as using the workspaces feature to allow easy npm scripts to manage the code from the root of the project. If either of those are a dealbreaker, you can try downloading the repo via the download link and update it as needed.</p>
<h3 id="heading-cloning-the-hook-template-from-git">Cloning the hook template from git</h3>
<p>To start, let’s clone the repository from Github. In the command below, you should replace <code>use-my-custom-hook</code> with the name of your hook, such as <code>use-cookies</code> or <code>use-mooncake</code>.</p>
<pre><code class="lang-shell">git clone https://github.com/colbyfayock/use-custom-hook use-my-custom-hook
cd use-my-custom-hook
</code></pre>
<p>Once you clone and navigate to that folder, you should now see 2 directories – an <code>example</code> directory and a <code>use-custom-hook</code> directory.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/cloning-use-custom-hook-1.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Cloning use-custom-hook</em></p>
<p>This will give you a few things to get started:</p>
<ul>
<li>A hook directory that will include the source for our hook</li>
<li>Build scripts that compile our hook with <a target="_blank" href="https://babeljs.io/">babel</a></li>
<li>An example page that imports our hook and creates a simple demo page with <a target="_blank" href="https://nextjs.org/">next.js</a></li>
</ul>
<h3 id="heading-running-the-hook-setup-scripts">Running the hook setup scripts</h3>
<p>After we successfully clone the repo, we want to run the setup scripts which install dependencies and update the hook to the name we want.</p>
<pre><code class="lang-shell">yarn install &amp;&amp; yarn setup
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/setting-up-new-hook-template.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Setting up a new hook from the use-custom-hook template</em></p>
<p>When the setup script runs, it will do a few things:</p>
<ul>
<li>It will ask you for your name – this is used to update the LICENSE and the package's author name</li>
<li>It will ask you for your hook's name in 2 variations – camelCase and snake-case - this will be used to update the name of the hook throughout the template and move files with that name to the correct location</li>
<li>It will reset git – it will first remove the local .git folder, which contains the history from my template and reinitialize git with a fresh commit to start your new history in</li>
<li>Finally, it will remove the setup script directory and remove the package dependencies that were only being used by those scripts</li>
</ul>
<h3 id="heading-starting-the-development-server">Starting the development server</h3>
<p>Once the setup scripts finish running, you'll want to run:</p>
<pre><code class="lang-shell">yarn develop
</code></pre>
<p>This runs a watch process on the hook source, building the hook locally each time a source file is changed, and running the example app server, where you can test the hook and make changes to the example pages.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/custom-hook-development-server.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Starting up the use-custom-hook development server</em></p>
<p>With this all ready, we can get started!</p>
<p><a target="_blank" href="https://github.com/colbyfayock/use-my-custom-hook/commits/master">Follow along with the commit!</a></p>
<h2 id="heading-step-2-writing-your-new-react-hook">Step 2: Writing your new React Hook</h2>
<p>At this point, you should now have a new custom hook where you can make it do whatever you'd like. But since we're going to walk through rebuilding the <a target="_blank" href="https://github.com/colbyfayock/use-placecage">usePlaceCage</a> hook, let's start there.</p>
<p>The usePlaceCage hook does 1 simple thing from a high level view – it takes in a configuration object and returns a number of image URLs that you can then use for your app.</p>
<p>Just as a reminder, any time I mention <code>usePlaceCage</code> or <code>use-placecage</code>, you should use the hook name that you set up before.</p>
<h3 id="heading-a-little-bit-about-placecagecom">A little bit about placecage.com</h3>
<p>Placecage.com is a placeholder image service that does 1 thing. It takes a URL with a simple configuration and returns an image... of Nic Cage.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/placecage-website.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>placecage.com</em></p>
<p>From the simplest use, the service uses a URL pattern as follows:</p>
<pre><code>https:<span class="hljs-comment">//www.placecage.com/200/300</span>
</code></pre><p>This would return an image with a width of 200 and height of 300.</p>
<p>Optionally, you can pass an additional URL parameter that defines the type of image:</p>
<pre><code>https:<span class="hljs-comment">//www.placecage.com/gif/200/300</span>
</code></pre><p>In this particular instance, our type is <code>gif</code>, so we'll receive a gif.</p>
<p>The different types available to use are:</p>
<ul>
<li>Nothing: calm</li>
<li><code>g</code>: gray</li>
<li><code>c</code>: crazy</li>
<li><code>gif</code>: gif</li>
</ul>
<p>We'll use this to define how we set up configuration for our hook.</p>
<h3 id="heading-defining-our-core-generator-function">Defining our core generator function</h3>
<p>To get started, we're going to copy over a function at the bottom of our <code>use-placecage/src/usePlaceCage.js</code> file, which allows us to generate an image URL, as well as a few constant definitions that we'll use in that function.</p>
<p>First, let's copy over our constants to the top of our <code>usePlaceCage.js</code> file:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> PLACECAGE_HOST = <span class="hljs-string">'https://www.placecage.com/'</span>;
<span class="hljs-keyword">const</span> TYPES = {
  <span class="hljs-attr">calm</span>: <span class="hljs-literal">null</span>,
  <span class="hljs-attr">gray</span>: <span class="hljs-string">'g'</span>,
  <span class="hljs-attr">crazy</span>: <span class="hljs-string">'c'</span>,
  <span class="hljs-attr">gif</span>: <span class="hljs-string">'gif'</span>
};
<span class="hljs-keyword">const</span> DEFAULT_TYPE = <span class="hljs-string">'calm'</span>;
<span class="hljs-keyword">const</span> ERROR_BASE = <span class="hljs-string">'Failed to place Nick'</span>;
</code></pre>
<p>Here we:</p>
<ul>
<li>Define a host, which is the base URL of our image service.</li>
<li>Define the available types, which we'll use in the configuration API. We set <code>calm</code> to <code>null</code>, because it's the default value which you get by not including it at all</li>
<li>Our default type will be <code>calm</code></li>
<li>And we set an error base which is a consistent message when throwing an error</li>
</ul>
<p>Then for our function, let's copy this at the bottom of our <code>usePlaceCage.js</code> file:</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">generateCage</span>(<span class="hljs-params">settings</span>) </span>{
  <span class="hljs-keyword">const</span> { type = DEFAULT_TYPE, width = <span class="hljs-number">200</span>, height = <span class="hljs-number">200</span>, count = <span class="hljs-number">1</span> } = settings;
  <span class="hljs-keyword">const</span> config = [];

  <span class="hljs-keyword">if</span> ( type !== DEFAULT_TYPE &amp;&amp; TYPES[type] ) {
    config.push(TYPES[type]);
  }

  config.push(width, height);

  <span class="hljs-keyword">if</span> ( <span class="hljs-built_in">isNaN</span>(count) ) {
    <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">`<span class="hljs-subst">${ERROR_BASE}</span>: Invalid count <span class="hljs-subst">${count}</span>`</span>);
  }

  <span class="hljs-keyword">return</span> [...new <span class="hljs-built_in">Array</span>(count)].map(<span class="hljs-function">() =&gt;</span> <span class="hljs-string">`<span class="hljs-subst">${PLACECAGE_HOST}</span><span class="hljs-subst">${config.join(<span class="hljs-string">'/'</span>)}</span>`</span>);
}
</code></pre>
<p>Walking through this code:</p>
<ul>
<li>We define a <code>generateCage</code> function which we'll use to generate our image URL</li>
<li>We take in a settings object as an argument, which defines the configuration of our image URL. We'll be using the same parameters as we saw in our placecage.com URL</li>
<li>We destructure those settings to make them available for us to use</li>
<li>We have a few defaults here just to make it easier. Our default <code>type</code> will be defined by <code>DEFAULT_TYPE</code> along with a default width, height, and number of results we want to return</li>
<li>We create a <code>config</code> array. We'll use this  to append all of the different configuration objects in our URL and finally join them together with a <code>/</code> essentially making a URL</li>
<li>Before we push our config to that array, we check if it's a valid argument, by using the <code>TYPES</code> object to check against it. If it's valid, we push it to our config array</li>
<li>We then push our width and height</li>
<li>We do some type checking, if we don't have a valid number as the <code>count</code>, we throw an error, otherwise we'll get incorrect results</li>
<li>Finally, we return a new array with the number of results requested, mapped to a URL creator, which uses <code>PLACECAGE_HOST</code> as our defined base URL, and with our config array joined by <code>/</code></li>
</ul>
<p>And if we were to test this function, it would look like this:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> cage = generateCage({
  <span class="hljs-attr">type</span>: <span class="hljs-string">'gif'</span>,
  <span class="hljs-attr">width</span>: <span class="hljs-number">500</span>,
  <span class="hljs-attr">height</span>: <span class="hljs-number">500</span>,
  <span class="hljs-attr">count</span>: <span class="hljs-number">2</span>
});

<span class="hljs-built_in">console</span>.log(cage); <span class="hljs-comment">// ['https://www.placecage.com/gif/500/500', 'https://www.placecage.com/gif/500/500']</span>
</code></pre>
<h3 id="heading-using-our-function-in-the-hook">Using our function in the hook</h3>
<p>So now that we have our generator function, let's actually use it in our hook!</p>
<p>Inside of the <code>usePlaceCage</code> function in the <code>use-placecage/src/usePlaceCage.js</code> file, we can add:</p>
<pre><code class="lang-js"><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">usePlaceCage</span> (<span class="hljs-params">settings = {}</span>) </span>{
  <span class="hljs-keyword">return</span> generateCage(settings);
}
</code></pre>
<p>What this does it uses our generator function, takes in the settings that were passed into the hook, and returns that value from the hook.</p>
<p>Similar to our previous use example, if we were to use our hook, it would look like this:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> cage = usePlaceCage({
  <span class="hljs-attr">type</span>: <span class="hljs-string">'gif'</span>,
  <span class="hljs-attr">width</span>: <span class="hljs-number">500</span>,
  <span class="hljs-attr">height</span>: <span class="hljs-number">500</span>,
  <span class="hljs-attr">count</span>: <span class="hljs-number">2</span>
});

<span class="hljs-built_in">console</span>.log(cage); <span class="hljs-comment">// ['https://www.placecage.com/gif/500/500', 'https://www.placecage.com/gif/500/500']</span>
</code></pre>
<p>At this point, it does the same thing!</p>
<p>So now we have our hook, it serves as a function to generate image URLs for the placecage.com service. How can we actually use it?</p>
<p><a target="_blank" href="https://github.com/colbyfayock/use-my-custom-hook/commit/a4d4d3c3565759031c29d00faf731ac4c236a1fd">Follow along with the commit!</a></p>
<h2 id="heading-step-3-using-your-react-hook-in-an-example">Step 3: Using your React hook in an example</h2>
<p>The good news about our template, is it already includes an example app that we can update to easily make use of our hook to both test and provide documentation for those who want to use it.</p>
<h3 id="heading-setting-up-the-hook">Setting up the hook</h3>
<p>To get started, let's open up our <code>example/pages/index.js</code> file. Inside of this file you'll see the following:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> hookSettings = {
  <span class="hljs-attr">message</span>: <span class="hljs-string">'Hello, custom hook!'</span>
}

<span class="hljs-keyword">const</span> { message } = usePlaceCage(hookSettings);
</code></pre>
<p>This snippet is what was used by default in the template just for a proof of concept, so let's update that. We're going to use the same exact configuration as we did in Step 2:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> hookSettings = {
  <span class="hljs-attr">type</span>: <span class="hljs-string">'gif'</span>,
  <span class="hljs-attr">width</span>: <span class="hljs-number">500</span>,
  <span class="hljs-attr">height</span>: <span class="hljs-number">500</span>,
  <span class="hljs-attr">count</span>: <span class="hljs-number">2</span>
}

<span class="hljs-keyword">const</span> cage = usePlaceCage(hookSettings);
</code></pre>
<p>Again, we set up our settings object with the configuration for our hook and invoke our hook and set the value to the <code>cage</code> constant.</p>
<p>If we now console log that value our to our dev tools, we can see it working!</p>
<pre><code class="lang-js"><span class="hljs-built_in">console</span>.log(<span class="hljs-string">'cage'</span>, cage);
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/console-log-cage-array.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Using console.log to show the cage value</em></p>
<p><em>Note: If you get an error here about <code>message</code>, you  can comment that our or remove it under the Examples section.</em></p>
<h3 id="heading-updating-the-example-with-our-new-hook-configuration">Updating the example with our new hook configuration</h3>
<p>If you scroll down to the Examples section, you'll notice that we have the same default <code>hookSettings</code> as above, so let's update that again to make sure our example is accurate.</p>
<pre><code class="lang-jsx">{<span class="hljs-string">`const hookSettings = {
  type: 'gif',
  width: 500,
  height: 500,
  count: 2
}

const cage = usePlaceCage(hookSettings);`</span>}
</code></pre>
<p>You'll also notice that we're no longer using the <code>message</code> variable. If you didn't remove it in the last step, we can now replace it under the Output heading with:</p>
<pre><code class="lang-jsx">&lt;p&gt;
  { <span class="hljs-built_in">JSON</span>.stringify(cage) }
&lt;/p&gt;
<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>
  { cage.map((img, i) =&gt; <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">key</span>=<span class="hljs-string">{</span>`<span class="hljs-attr">img-</span>${<span class="hljs-attr">i</span>}`} <span class="hljs-attr">width</span>=<span class="hljs-string">{200}</span> <span class="hljs-attr">src</span>=<span class="hljs-string">{img}</span> /&gt;</span>)}
<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span></span>
</code></pre>
<p>We're doing 2 things here:</p>
<ul>
<li>Instead of showing the variable itself, we wrap it with <code>JSON.stringify</code> so that we can show the contents of the array</li>
<li>We also use the <code>map</code> function to loop over our image URLs in the <code>cage</code> constant and create a new image element for each. This let's us preview the output instead of just seeing the values</li>
</ul>
<p>And once you save and open your browser, you should now see your updated examples and output!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/custom-hook-example-page.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Custom hook example page</em></p>
<h3 id="heading-other-things-you-can-do-on-that-page">Other things you can do on that page</h3>
<p>Before moving on, you can also update a few other things that will be important for your hooks page:</p>
<ul>
<li>Update the <strong>How to use</strong> section with instructions</li>
<li>Add additional examples to make it easier for people to know what to do</li>
</ul>
<p>A  few things are also automatically pulled in from the <code>use-placecage/package.json</code> file. You can either update them there to make it easier to maintain or you can replace them in the example page:</p>
<ul>
<li><code>name</code>: Is used at the <code>&lt;h1&gt;</code> of the page</li>
<li><code>description</code>: Is used at the description under the <code>&lt;h1&gt;</code></li>
<li><code>repository.url</code>: Used to include a link to the repository</li>
<li><code>author</code>: The <code>name</code> and <code>url</code> are used to include a link at the bottom of the page</li>
</ul>
<p><a target="_blank" href="https://github.com/colbyfayock/use-my-custom-hook/commit/71ae57b562ad814d0ce862c22e247aa8c450b6cf">Follow along with the commit!</a></p>
<h2 id="heading-step-4-compiling-your-react-hook-and-example">Step 4: Compiling your React hook and Example</h2>
<p>The way we can make our hook work easily as an npm module is to compile it for others to use. We're using babel to do this.</p>
<p>Though the publish process already does this for us automatically with the <code>prepublishOnly</code> script in <code>use-placecage/package.json</code>, we can manually compile our hook using the <code>yarn build</code> command from the root of the project.</p>
<p>Along with compiling the hook, running <code>yarn build</code> will also compile the example page, allowing you to upload it wherever you'd like. After running that command, you should see an output of static HTML files in the <code>example/out</code> directory.</p>
<p>If you're looking for a recommendation, <a target="_blank" href="https://www.netlify.com/">Netlify</a> makes it easy to connect your <a target="_blank" href="https://github.com/">Github</a> account and deploy the static site.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/netlify-deployment-setup.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Deployment setup in Netlify</em></p>
<p><a target="_blank" href="https://use-my-custom-hook.netlify.com/">See the demo site deployed to Netlify!</a></p>
<h2 id="heading-step-5-publishing-your-react-hook-to-npm">Step 5: Publishing your React hook to npm</h2>
<p>Finally, if you're happy with your hook, it's time to publish!</p>
<p>npm makes this part really easy. The only prerequisite you need to have an npm account. With that account, let's log in:</p>
<pre><code class="lang-shell">npm login
</code></pre>
<p>Which will prompt you for your login credentials.</p>
<p>Next, let's navigate to our hook's directory, as our package configuration is there under <code>use-placecage/package.json</code>:</p>
<pre><code class="lang-shell">cd use-placecage
</code></pre>
<p>Then, we can simply publish!</p>
<pre><code class="lang-shell">npm publish
</code></pre>
<p>Keep in mind, that each package name needs to be unique. If you used <code>use-placecage</code>, it's already taken... by me. ?</p>
<p>But if you're successful, npm should build your hook and upload it to the package registry!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/publishing-npm-package.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Publishing an npm package</em></p>
<p>It will then be available on npm with the following pattern:</p>
<pre><code>https:<span class="hljs-comment">//www.npmjs.com/package/[package-name]</span>
</code></pre><p>So for <code>use-placeage</code>, it's available here: <a target="_blank" href="https://www.npmjs.com/package/use-placecage">https://www.npmjs.com/package/use-placecage</a></p>
<h2 id="heading-we-now-have-a-custom-hook">We now have a custom hook!</h2>
<p>Yay ? if you followed along, you should now have created a custom hook and published it to npm.</p>
<p>Though this was a silly example using placecage.com, it gives us a good idea of how we can easily set this up.</p>
<p>You'll also notice that this specific example wasn't the best use case for a hooks, where we could have simply used a function. Typically, we'll want to use custom hooks to wrap functionality that can only live inside a React component, such as <code>useState</code>. To learn more about that, you can read one of my other <a target="_blank" href="https://www.freecodecamp.org/news/how-to-destructure-the-fundamentals-of-react-hooks-d13ff6ea6871/">articles about custom hooks</a>.</p>
<p>However, this gave us a good basis to talk through the creation and configuration of our new hook!</p>
<h2 id="heading-more-resources-about-hooks">More resources about hooks</h2>
<ul>
<li><a target="_blank" href="https://www.freecodecamp.org/news/how-to-destructure-the-fundamentals-of-react-hooks-d13ff6ea6871/">How to destructure the fundamentals of React Hooks</a> (freecodecamp.org)</li>
<li><a target="_blank" href="https://reactjs.org/docs/hooks-intro.html">Introducing Hooks</a> (reactjs.org)</li>
<li><a target="_blank" href="https://reactjs.org/docs/hooks-reference.html">Hooks API Reference</a> (reactjs.org)</li>
</ul>
<div id="colbyfayock-author-card">
  <p>
    <a href="https://twitter.com/colbyfayock">
      <img src="https://res.cloudinary.com/fay/image/upload/w_2000,h_400,c_fill,q_auto,f_auto/w_1020,c_fit,co_rgb:007079,g_north_west,x_635,y_70,l_text:Source%20Sans%20Pro_64_line_spacing_-10_bold:Colby%20Fayock/w_1020,c_fit,co_rgb:383f43,g_west,x_635,y_6,l_text:Source%20Sans%20Pro_44_line_spacing_0_normal:Follow%20me%20for%20more%20JavaScript%252c%20UX%252c%20and%20other%20interesting%20things!/w_1020,c_fit,co_rgb:007079,g_south_west,x_635,y_70,l_text:Source%20Sans%20Pro_40_line_spacing_-10_semibold:colbyfayock.com/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_68,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_145,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_222,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_295,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/v1/social-footer-card" alt="Follow me for more Javascript, UX, and other interesting things!" width="2000" height="400" loading="lazy">
    </a>
  </p>
  <ul>
    <li>
      <a href="https://twitter.com/colbyfayock">? Follow Me On Twitter</a>
    </li>
    <li>
      <a href="https://youtube.com/colbyfayock">?️ Subscribe To My Youtube</a>
    </li>
    <li>
      <a href="https://www.colbyfayock.com/newsletter/">✉️ Sign Up For My Newsletter</a>
    </li>
  </ul>
</div>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Angular Lifecycle Hooks: ngOnChanges, ngOnInit, and more ]]>
                </title>
                <description>
                    <![CDATA[ Why do we need lifecycle hooks? Modern front-end frameworks move the application from state to state. Data fuels these updates. These technologies interact with the data which in turn transitions the state. With every state change, there are many spe... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/angular-lifecycle-hooks/</link>
                <guid isPermaLink="false">66c344b8f9d371e3aae26827</guid>
                
                    <category>
                        <![CDATA[ Angular ]]>
                    </category>
                
                    <category>
                        <![CDATA[ hooks ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Mon, 27 Jan 2020 21:53:00 +0000</pubDate>
                <media:content url="https://cdn-media-2.freecodecamp.org/w1280/5f9c9d66740569d1a4ca378c.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <h3 id="heading-why-do-we-need-lifecycle-hooks">Why do we need lifecycle hooks?</h3>
<p>Modern front-end frameworks move the application from state to state. Data fuels these updates. These technologies interact with the data which in turn transitions the state. With every state change, there are many specific moments where certain assets become available.</p>
<p>At one instance the template might be ready, in another data will have finished uploading. Coding for each instance requires a means of detection. Lifecycle hooks answer this need. Modern front-end frameworks package themselves with a variety of lifecycle hooks. Angular is no exception</p>
<h2 id="heading-lifecycle-hooks-explained">Lifecycle Hooks Explained</h2>
<p>Lifecycle hooks are timed methods. They differ in when and why they execute. Change detection triggers these methods. They execute depending on the conditions of the current cycle. Angular runs change detection constantly on its data. Lifecycle hooks help manage its effects.</p>
<p>An important aspect of these hooks is their order of execution. It never deviates. They execute based on a predictable series of load events produced from a detection cycle. This makes them predictable. </p>
<p>Some assets are only available after a certain hook executes. Of course, a hook only execute under certain conditions set in the current change detection cycle.</p>
<p>This article presents the lifecycle hooks in order of their execution (if they all execute). Certain conditions merit a hook’s activation. There are a few who only execute once after component initialization.</p>
<p>All lifecycle methods are available from <code>@angular/core</code>. Although not required, Angular <a target="_blank" href="https://angular.io/guide/lifecycle-hooks#interfaces-are-optional-technically">recommends implementing every hook</a>. This practice leads to better error messages regarding the component.</p>
<h2 id="heading-order-of-lifecycle-hooks-execution">Order of Lifecycle Hooks' Execution</h2>
<h3 id="heading-ngonchanges">ngOnChanges</h3>
<p><code>ngOnChanges</code> triggers following the modification of <code>@Input</code> bound class members. Data bound by the <code>@Input()</code> decorator come from an external source. When the external source alters that data in a detectable manner, it passes through the <code>@Input</code> property again.</p>
<p>With this update, <code>ngOnChanges</code> immediately fires. It also fires upon initialization of input data. The hook receives one optional parameter of type <code>SimpleChanges</code>. This value contains information on the changed input-bound properties.</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { Component, Input, OnChanges } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/core'</span>;

<span class="hljs-meta">@Component</span>({
  selector: <span class="hljs-string">'app-child'</span>,
  template: <span class="hljs-string">`
  &lt;h3&gt;Child Component&lt;/h3&gt;
  &lt;p&gt;TICKS: {{ lifecycleTicks }}&lt;/p&gt;
  &lt;p&gt;DATA: {{ data }}&lt;/p&gt;
  `</span>
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> ChildComponent <span class="hljs-keyword">implements</span> OnChanges {
  <span class="hljs-meta">@Input</span>() data: <span class="hljs-built_in">string</span>;
  lifecycleTicks: <span class="hljs-built_in">number</span> = <span class="hljs-number">0</span>;

  ngOnChanges() {
    <span class="hljs-built_in">this</span>.lifecycleTicks++;
  }
}

<span class="hljs-meta">@Component</span>({
  selector: <span class="hljs-string">'app-parent'</span>,
  template: <span class="hljs-string">`
  &lt;h1&gt;ngOnChanges Example&lt;/h1&gt;
  &lt;app-child [data]="arbitraryData"&gt;&lt;/app-child&gt;
  `</span>
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> ParentComponent {
  arbitraryData: <span class="hljs-built_in">string</span> = <span class="hljs-string">'initial'</span>;

  <span class="hljs-keyword">constructor</span>(<span class="hljs-params"></span>) {
    <span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">() =&gt;</span> {
      <span class="hljs-built_in">this</span>.arbitraryData = <span class="hljs-string">'final'</span>;
    }, <span class="hljs-number">5000</span>);
  }
}
</code></pre>
<p><strong>Summary:</strong> ParentComponent binds input data to the ChildComponent. The component receives this data through its <code>@Input</code> property. <code>ngOnChanges</code> fires. After five seconds, the <code>setTimeout</code> callback triggers. ParentComponent mutates the data source of ChildComponent’s input-bound property. The new data flows through the input property. <code>ngOnChanges</code> fires yet again.</p>
<h3 id="heading-ngoninit">ngOnInit</h3>
<p><code>ngOnInit</code> fires once upon initialization of a component’s input-bound (<code>@Input</code>) properties. The next example will look similar to the last one. The hook does not fire as ChildComponent receives the input data. Rather, it fires right after the data renders to the ChildComponent template.</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { Component, Input, OnInit } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/core'</span>;

<span class="hljs-meta">@Component</span>({
  selector: <span class="hljs-string">'app-child'</span>,
  template: <span class="hljs-string">`
  &lt;h3&gt;Child Component&lt;/h3&gt;
  &lt;p&gt;TICKS: {{ lifecycleTicks }}&lt;/p&gt;
  &lt;p&gt;DATA: {{ data }}&lt;/p&gt;
  `</span>
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> ChildComponent <span class="hljs-keyword">implements</span> OnInit {
  <span class="hljs-meta">@Input</span>() data: <span class="hljs-built_in">string</span>;
  lifecycleTicks: <span class="hljs-built_in">number</span> = <span class="hljs-number">0</span>;

  ngOnInit() {
    <span class="hljs-built_in">this</span>.lifecycleTicks++;
  }
}

<span class="hljs-meta">@Component</span>({
  selector: <span class="hljs-string">'app-parent'</span>,
  template: <span class="hljs-string">`
  &lt;h1&gt;ngOnInit Example&lt;/h1&gt;
  &lt;app-child [data]="arbitraryData"&gt;&lt;/app-child&gt;
  `</span>
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> ParentComponent {
  arbitraryData: <span class="hljs-built_in">string</span> = <span class="hljs-string">'initial'</span>;

  <span class="hljs-keyword">constructor</span>(<span class="hljs-params"></span>) {
    <span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">() =&gt;</span> {
      <span class="hljs-built_in">this</span>.arbitraryData = <span class="hljs-string">'final'</span>;
    }, <span class="hljs-number">5000</span>);
  }
}
</code></pre>
<p><strong>Summary:</strong> ParentComponent binds input data to the ChildComponent. ChildComponent receives this data through its <code>@Input</code> property. The data renders to the template. <code>ngOnInit</code> fires. After five seconds, the <code>setTimeout</code> callback triggers. ParentComponent mutates the data source of ChildComponent’s input-bound property. ngOnInit <strong>DOES NOT FIRE</strong>.</p>
<p><code>ngOnInit</code> is a one-and-done hook. Initialization is its only concern.</p>
<h3 id="heading-ngdocheck">ngDoCheck</h3>
<p><code>ngDoCheck</code> fires with every change detection cycle. Angular runs change detection frequently. Performing any action will cause it to cycle. <code>ngDoCheck</code> fires with these cycles. Use it with caution. It can create performance issues when implemented incorrectly.</p>
<p><code>ngDoCheck</code> lets developers check their data manually. They can trigger a new application date conditionally. In conjunction with <code>ChangeDetectorRef</code>, developers can create their own checks for change detection.</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { Component, DoCheck, ChangeDetectorRef } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/core'</span>;

<span class="hljs-meta">@Component</span>({
  selector: <span class="hljs-string">'app-example'</span>,
  template: <span class="hljs-string">`
  &lt;h1&gt;ngDoCheck Example&lt;/h1&gt;
  &lt;p&gt;DATA: {{ data[data.length - 1] }}&lt;/p&gt;
  `</span>
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> ExampleComponent <span class="hljs-keyword">implements</span> DoCheck {
  lifecycleTicks: <span class="hljs-built_in">number</span> = <span class="hljs-number">0</span>;
  oldTheData: <span class="hljs-built_in">string</span>;
  data: <span class="hljs-built_in">string</span>[] = [<span class="hljs-string">'initial'</span>];

  <span class="hljs-keyword">constructor</span>(<span class="hljs-params"><span class="hljs-keyword">private</span> changeDetector: ChangeDetectorRef</span>) {
    <span class="hljs-built_in">this</span>.changeDetector.detach(); <span class="hljs-comment">// lets the class perform its own change detection</span>

    <span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">() =&gt;</span> {
      <span class="hljs-built_in">this</span>.oldTheData = <span class="hljs-string">'final'</span>; <span class="hljs-comment">// intentional error</span>
      <span class="hljs-built_in">this</span>.data.push(<span class="hljs-string">'intermediate'</span>);
    }, <span class="hljs-number">3000</span>);

    <span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">() =&gt;</span> {
      <span class="hljs-built_in">this</span>.data.push(<span class="hljs-string">'final'</span>);
      <span class="hljs-built_in">this</span>.changeDetector.markForCheck();
    }, <span class="hljs-number">6000</span>);
  }

  ngDoCheck() {
    <span class="hljs-built_in">console</span>.log(++<span class="hljs-built_in">this</span>.lifecycleTicks);

    <span class="hljs-keyword">if</span> (<span class="hljs-built_in">this</span>.data[<span class="hljs-built_in">this</span>.data.length - <span class="hljs-number">1</span>] !== <span class="hljs-built_in">this</span>.oldTheData) {
      <span class="hljs-built_in">this</span>.changeDetector.detectChanges();
    }
  }
}
</code></pre>
<p>Pay attention to the console versus the display. The data progress up to ‘intermediate’ before freezing. Three rounds of change detection occur over this period as indicated in the console. One more round of change detection occurs as ‘final’ gets pushed to the end of <code>this.data</code>. One last round of change detection then occurs. The evaluation of the if statement determines no updates to the view are necessary.</p>
<p><strong>Summary:</strong> Class instantiates after two rounds of change detection. Class constructor initiates <code>setTimeout</code> twice. After three seconds, the first <code>setTimeout</code> triggers change detection. <code>ngDoCheck</code> marks the display for an update. Three seconds later, the second <code>setTimeout</code> triggers change detection. No view updates needed according to the evaluation of <code>ngDoCheck</code>.</p>
<h3 id="heading-warning">Warning</h3>
<p>Before proceeding, learn the difference between the content DOM and view DOM (DOM stands for Document Object Model).</p>
<p>The content DOM defines the innerHTML of directive elements. Conversely, the view DOM is a component’s template excluding any template HTML nested within a directive. For a better understanding, refer to <a target="_blank" href="http://blog.mgechev.com/2016/01/23/angular2-viewchildren-contentchildren-difference-viewproviders">this blog post</a>.</p>
<h3 id="heading-ngaftercontentinit">ngAfterContentInit</h3>
<p><code>ngAfterContentInit</code> fires after the component’s content DOM initializes (loads for the first time). Waiting on <code>@ContentChild(ren)</code> queries is the hook’s primary use-case.</p>
<p><code>@ContentChild(ren)</code> queries yield element references for the content DOM. As such, they are not available until after the content DOM loads. Hence why <code>ngAfterContentInit</code> and its counterpart <code>ngAfterContentChecked</code> are used.</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { Component, ContentChild, AfterContentInit, ElementRef, Renderer2 } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/core'</span>;

<span class="hljs-meta">@Component</span>({
  selector: <span class="hljs-string">'app-c'</span>,
  template: <span class="hljs-string">`
  &lt;p&gt;I am C.&lt;/p&gt;
  &lt;p&gt;Hello World!&lt;/p&gt;
  `</span>
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> CComponent { }

<span class="hljs-meta">@Component</span>({
  selector: <span class="hljs-string">'app-b'</span>,
  template: <span class="hljs-string">`
  &lt;p&gt;I am B.&lt;/p&gt;
  &lt;ng-content&gt;&lt;/ng-content&gt;
  `</span>
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> BComponent <span class="hljs-keyword">implements</span> AfterContentInit {
  <span class="hljs-meta">@ContentChild</span>(<span class="hljs-string">"BHeader"</span>, { read: ElementRef }) hRef: ElementRef;
  <span class="hljs-meta">@ContentChild</span>(CComponent, { read: ElementRef }) cRef: ElementRef;

  <span class="hljs-keyword">constructor</span>(<span class="hljs-params"><span class="hljs-keyword">private</span> renderer: Renderer2</span>) { }

  ngAfterContentInit() {
    <span class="hljs-built_in">this</span>.renderer.setStyle(<span class="hljs-built_in">this</span>.hRef.nativeElement, <span class="hljs-string">'background-color'</span>, <span class="hljs-string">'yellow'</span>)

    <span class="hljs-built_in">this</span>.renderer.setStyle(<span class="hljs-built_in">this</span>.cRef.nativeElement.children.item(<span class="hljs-number">0</span>), <span class="hljs-string">'background-color'</span>, <span class="hljs-string">'pink'</span>);
    <span class="hljs-built_in">this</span>.renderer.setStyle(<span class="hljs-built_in">this</span>.cRef.nativeElement.children.item(<span class="hljs-number">1</span>), <span class="hljs-string">'background-color'</span>, <span class="hljs-string">'red'</span>);
  }
}

<span class="hljs-meta">@Component</span>({
  selector: <span class="hljs-string">'app-a'</span>,
  template: <span class="hljs-string">`
  &lt;h1&gt;ngAfterContentInit Example&lt;/h1&gt;
  &lt;p&gt;I am A.&lt;/p&gt;
  &lt;app-b&gt;
    &lt;h3 #BHeader&gt;BComponent Content DOM&lt;/h3&gt;
    &lt;app-c&gt;&lt;/app-c&gt;
  &lt;/app-b&gt;
  `</span>
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> AComponent { }
</code></pre>
<p>The <code>@ContentChild</code> query results are available from <code>ngAfterContentInit</code>. <code>Renderer2</code> updates the content DOM of BComponent containing a <code>h3</code> tag and CComponent. This is a common example of <a target="_blank" href="https://alligator.io/angular/content-projection-angular">content projection</a>.</p>
<p><strong>Summary:</strong> Rendering starts with AComponent. For it to finish, AComponent must render BComponent. BComponent projects content nested in its element through the <code>&lt;ng-content&gt;&lt;/ng-content&gt;</code> element. CComponent is part of the projected content. The projected content finishes rendering. <code>ngAfterContentInit</code> fires. BComponent finishes rendering. AComponent finishes rendering. <code>ngAfterContentInit</code> will not fire again.</p>
<h3 id="heading-ngaftercontentchecked">ngAfterContentChecked</h3>
<p><code>ngAfterContentChecked</code> fires after every cycle of change detection targeting the content DOM. This lets developers facilitate how the content DOM reacts to change detection. <code>ngAfterContentChecked</code> can fire frequently and cause performance issues if poorly implemented.</p>
<p><code>ngAfterContentChecked</code> fires during a component’s initialization stages too. It comes right after <code>ngAfterContentInit</code>.</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { Component, ContentChild, AfterContentChecked, ElementRef, Renderer2 } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/core'</span>;

<span class="hljs-meta">@Component</span>({
  selector: <span class="hljs-string">'app-c'</span>,
  template: <span class="hljs-string">`
  &lt;p&gt;I am C.&lt;/p&gt;
  &lt;p&gt;Hello World!&lt;/p&gt;
  `</span>
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> CComponent { }

<span class="hljs-meta">@Component</span>({
  selector: <span class="hljs-string">'app-b'</span>,
  template: <span class="hljs-string">`
  &lt;p&gt;I am B.&lt;/p&gt;
  &lt;button (click)="$event"&gt;CLICK&lt;/button&gt;
  &lt;ng-content&gt;&lt;/ng-content&gt;
  `</span>
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> BComponent <span class="hljs-keyword">implements</span> AfterContentChecked {
  <span class="hljs-meta">@ContentChild</span>(<span class="hljs-string">"BHeader"</span>, { read: ElementRef }) hRef: ElementRef;
  <span class="hljs-meta">@ContentChild</span>(CComponent, { read: ElementRef }) cRef: ElementRef;

  <span class="hljs-keyword">constructor</span>(<span class="hljs-params"><span class="hljs-keyword">private</span> renderer: Renderer2</span>) { }

  randomRGB(): <span class="hljs-built_in">string</span> {
    <span class="hljs-keyword">return</span> <span class="hljs-string">`rgb(<span class="hljs-subst">${<span class="hljs-built_in">Math</span>.floor(<span class="hljs-built_in">Math</span>.random() * <span class="hljs-number">256</span>)}</span>,
    <span class="hljs-subst">${<span class="hljs-built_in">Math</span>.floor(<span class="hljs-built_in">Math</span>.random() * <span class="hljs-number">256</span>)}</span>,
    <span class="hljs-subst">${<span class="hljs-built_in">Math</span>.floor(<span class="hljs-built_in">Math</span>.random() * <span class="hljs-number">256</span>)}</span>)`</span>;
  }

  ngAfterContentChecked() {
    <span class="hljs-built_in">this</span>.renderer.setStyle(<span class="hljs-built_in">this</span>.hRef.nativeElement, <span class="hljs-string">'background-color'</span>, <span class="hljs-built_in">this</span>.randomRGB());
    <span class="hljs-built_in">this</span>.renderer.setStyle(<span class="hljs-built_in">this</span>.cRef.nativeElement.children.item(<span class="hljs-number">0</span>), <span class="hljs-string">'background-color'</span>, <span class="hljs-built_in">this</span>.randomRGB());
    <span class="hljs-built_in">this</span>.renderer.setStyle(<span class="hljs-built_in">this</span>.cRef.nativeElement.children.item(<span class="hljs-number">1</span>), <span class="hljs-string">'background-color'</span>, <span class="hljs-built_in">this</span>.randomRGB());
  }
}

<span class="hljs-meta">@Component</span>({
  selector: <span class="hljs-string">'app-a'</span>,
  template: <span class="hljs-string">`
  &lt;h1&gt;ngAfterContentChecked Example&lt;/h1&gt;
  &lt;p&gt;I am A.&lt;/p&gt;
  &lt;app-b&gt;
    &lt;h3 #BHeader&gt;BComponent Content DOM&lt;/h3&gt;
    &lt;app-c&gt;&lt;/app-c&gt;
  &lt;/app-b&gt;
  `</span>
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> AComponent { }
</code></pre>
<p>This hardly differs from <code>ngAfterContentInit</code>. A mere <code>&lt;button&gt;&lt;/button&gt;</code> was added to BComponent. Clicking it causes a change detection loop. This activates the hook as indicated by the randomization of <code>background-color</code>.</p>
<p><strong>Summary:</strong> Rendering starts with AComponent. For it to finish, AComponent must render BComponent. BComponent projects content nested in its element through the <code>&lt;ng-content&gt;&lt;/ng-content&gt;</code> element. CComponent is part of the projected content. The projected content finishes rendering. <code>ngAfterContentChecked</code> fires. BComponent finishes rendering. AComponent finishes rendering. <code>ngAfterContentChecked</code> may fire again through change detection.</p>
<h3 id="heading-ngafterviewinit">ngAfterViewInit</h3>
<p><code>ngAfterViewInit</code> fires once after the view DOM finishes initializing. The view always loads right after the content. <code>ngAfterViewInit</code> waits on <code>@ViewChild(ren)</code> queries to resolve. These elements are queried from within the same view of the component.</p>
<p>In the example below, BComponent’s <code>h3</code> header is queried. <code>ngAfterViewInit</code> executes as soon as the query’s results are available.</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { Component, ViewChild, AfterViewInit, ElementRef, Renderer2 } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/core'</span>;

<span class="hljs-meta">@Component</span>({
  selector: <span class="hljs-string">'app-c'</span>,
  template: <span class="hljs-string">`
  &lt;p&gt;I am C.&lt;/p&gt;
  &lt;p&gt;Hello World!&lt;/p&gt;
  `</span>
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> CComponent { }

<span class="hljs-meta">@Component</span>({
  selector: <span class="hljs-string">'app-b'</span>,
  template: <span class="hljs-string">`
  &lt;p #BStatement&gt;I am B.&lt;/p&gt;
  &lt;ng-content&gt;&lt;/ng-content&gt;
  `</span>
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> BComponent <span class="hljs-keyword">implements</span> AfterViewInit {
  <span class="hljs-meta">@ViewChild</span>(<span class="hljs-string">"BStatement"</span>, { read: ElementRef }) pStmt: ElementRef;

  <span class="hljs-keyword">constructor</span>(<span class="hljs-params"><span class="hljs-keyword">private</span> renderer: Renderer2</span>) { }

  ngAfterViewInit() {
    <span class="hljs-built_in">this</span>.renderer.setStyle(<span class="hljs-built_in">this</span>.pStmt.nativeElement, <span class="hljs-string">'background-color'</span>, <span class="hljs-string">'yellow'</span>);
  }
}

<span class="hljs-meta">@Component</span>({
  selector: <span class="hljs-string">'app-a'</span>,
  template: <span class="hljs-string">`
  &lt;h1&gt;ngAfterViewInit Example&lt;/h1&gt;
  &lt;p&gt;I am A.&lt;/p&gt;
  &lt;app-b&gt;
    &lt;h3&gt;BComponent Content DOM&lt;/h3&gt;
    &lt;app-c&gt;&lt;/app-c&gt;
  &lt;/app-b&gt;
  `</span>
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> AComponent { }
</code></pre>
<p><code>Renderer2</code> changes the background color of BComponent’s header. This indicates the view element was successfully queried thanks to <code>ngAfterViewInit</code>.</p>
<p><strong>Summary:</strong> Rendering starts with AComponent. For it to finish, AComponent must render BComponent. BComponent projects content nested in its element through the <code>&lt;ng-content&gt;&lt;/ng-content&gt;</code> element. CComponent is part of the projected content. The projected content finishes rendering. BComponent finishes rendering. <code>ngAfterViewInit</code> fires. AComponent finishes rendering. <code>ngAfterViewInit</code> will not fire again.</p>
<h3 id="heading-ngafterviewchecked">ngAfterViewChecked</h3>
<p><code>ngAfterViewChecked</code> fires after any change detection cycle targeting the component’s view. The <code>ngAfterViewChecked</code> hook lets developers facilitate how change detection affects the view DOM.</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { Component, ViewChild, AfterViewChecked, ElementRef, Renderer2 } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/core'</span>;

<span class="hljs-meta">@Component</span>({
  selector: <span class="hljs-string">'app-c'</span>,
  template: <span class="hljs-string">`
  &lt;p&gt;I am C.&lt;/p&gt;
  &lt;p&gt;Hello World!&lt;/p&gt;
  `</span>
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> CComponent { }

<span class="hljs-meta">@Component</span>({
  selector: <span class="hljs-string">'app-b'</span>,
  template: <span class="hljs-string">`
  &lt;p #BStatement&gt;I am B.&lt;/p&gt;
  &lt;button (click)="$event"&gt;CLICK&lt;/button&gt;
  &lt;ng-content&gt;&lt;/ng-content&gt;
  `</span>
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> BComponent <span class="hljs-keyword">implements</span> AfterViewChecked {
  <span class="hljs-meta">@ViewChild</span>(<span class="hljs-string">"BStatement"</span>, { read: ElementRef }) pStmt: ElementRef;

  <span class="hljs-keyword">constructor</span>(<span class="hljs-params"><span class="hljs-keyword">private</span> renderer: Renderer2</span>) { }

  randomRGB(): <span class="hljs-built_in">string</span> {
    <span class="hljs-keyword">return</span> <span class="hljs-string">`rgb(<span class="hljs-subst">${<span class="hljs-built_in">Math</span>.floor(<span class="hljs-built_in">Math</span>.random() * <span class="hljs-number">256</span>)}</span>,
    <span class="hljs-subst">${<span class="hljs-built_in">Math</span>.floor(<span class="hljs-built_in">Math</span>.random() * <span class="hljs-number">256</span>)}</span>,
    <span class="hljs-subst">${<span class="hljs-built_in">Math</span>.floor(<span class="hljs-built_in">Math</span>.random() * <span class="hljs-number">256</span>)}</span>)`</span>;
  }

  ngAfterViewChecked() {
    <span class="hljs-built_in">this</span>.renderer.setStyle(<span class="hljs-built_in">this</span>.pStmt.nativeElement, <span class="hljs-string">'background-color'</span>, <span class="hljs-built_in">this</span>.randomRGB());
  }
}

<span class="hljs-meta">@Component</span>({
  selector: <span class="hljs-string">'app-a'</span>,
  template: <span class="hljs-string">`
  &lt;h1&gt;ngAfterViewChecked Example&lt;/h1&gt;
  &lt;p&gt;I am A.&lt;/p&gt;
  &lt;app-b&gt;
    &lt;h3&gt;BComponent Content DOM&lt;/h3&gt;
    &lt;app-c&gt;&lt;/app-c&gt;
  &lt;/app-b&gt;
  `</span>
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> AComponent { }
</code></pre>
<p><strong>Summary:</strong> Rendering starts with AComponent. For it to finish, AComponent must render BComponent. BComponent projects content nested in its element through the <code>&lt;ng-content&gt;&lt;/ng-content&gt;</code> element. CComponent is part of the projected content. The projected content finishes rendering. BComponent finishes rendering. <code>ngAfterViewChecked</code> fires. AComponent finishes rendering. <code>ngAfterViewChecked</code> may fire again through change detection.</p>
<p>Clicking the <code>&lt;button&gt;&lt;/button&gt;</code> element initiates a round of change detection. <code>ngAfterContentChecked</code> fires and randomizes the <code>background-color</code> of the queried elements each button click.</p>
<h3 id="heading-ngondestroy">ngOnDestroy</h3>
<p><code>ngOnDestroy</code> fires upon a component’s removal from the view and subsequent DOM. This hook provides a chance to clean up any loose ends before a component’s deletion.</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { Directive, Component, OnDestroy } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/core'</span>;

<span class="hljs-meta">@Directive</span>({
  selector: <span class="hljs-string">'[appDestroyListener]'</span>
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> DestroyListenerDirective <span class="hljs-keyword">implements</span> OnDestroy {
  ngOnDestroy() {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Goodbye World!"</span>);
  }
}

<span class="hljs-meta">@Component</span>({
  selector: <span class="hljs-string">'app-example'</span>,
  template: <span class="hljs-string">`
  &lt;h1&gt;ngOnDestroy Example&lt;/h1&gt;
  &lt;button (click)="toggleDestroy()"&gt;TOGGLE DESTROY&lt;/button&gt;
  &lt;p appDestroyListener *ngIf="destroy"&gt;I can be destroyed!&lt;/p&gt;
  `</span>
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> ExampleComponent {
  destroy: <span class="hljs-built_in">boolean</span> = <span class="hljs-literal">true</span>;

  toggleDestroy() {
    <span class="hljs-built_in">this</span>.destroy = !<span class="hljs-built_in">this</span>.destroy;
  }
}
</code></pre>
<p><strong>Summary:</strong> The button is clicked. ExampleComponent’s <code>destroy</code> member toggles false. The structural directive <code>*ngIf</code> evaluates to false. <code>ngOnDestroy</code> fires. <code>*ngIf</code> removes its host <code>&lt;p&gt;&lt;/p&gt;</code>. This process repeats any number of times clicking the button to toggle <code>destroy</code> to false.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Remember that certain conditions must be met for each hook. They will always execute in order of each other regardless. This makes hooks predictable enough to work with even if some do not execute.</p>
<p>With lifecycle hooks, timing the execution of a class is easy. They let developers track where change detection is occurring and how the application should react. They stall for code that requires load-based dependencies available only after sometime.</p>
<p>The component lifecycle characterizes modern front end frameworks. Angular lays out its lifecycle by providing the aforementioned hooks.</p>
<h2 id="heading-sources"><strong>Sources</strong></h2>
<ul>
<li><a target="_blank" href="https://angular.io/guide/lifecycle-hooks">Angular Team. “Lifecycle Hooks”. <em>Google</em>. Accessed 2 June 2018</a></li>
<li><a target="_blank" href="http://blog.mgechev.com/2016/01/23/angular2-viewchildren-contentchildren-difference-viewproviders">Gechev, Minko. “ViewChildren and ContentChildren in Angular”. Accessed 2 June 2018</a></li>
</ul>
<h2 id="heading-resources"><strong>Resources</strong></h2>
<ul>
<li><a target="_blank" href="https://angular.io/docs">Angular Documentation</a></li>
<li><a target="_blank" href="https://github.com/angular/angular">Angular GitHub Repository</a></li>
<li><a target="_blank" href="https://angular.io/guide/lifecycle-hooks">Lifecycle Hooks in Depth</a></li>
</ul>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Learn the basics of React Hooks in <10 minutes ]]>
                </title>
                <description>
                    <![CDATA[ By Emmanuel Ohans Early this year, the React team released a new addition, hooks, to React in version 16.8.0. If React were a big bowl of candies, then hooks are the latest additions, very chewy candies with great taste! So, what exactly do hooks mea... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/learn-the-basics-of-react-hooks-in-10-minutes-b2898287fe5d/</link>
                <guid isPermaLink="false">66d45e58d14641365a0508c1</guid>
                
                    <category>
                        <![CDATA[ hooks ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ General Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                    <category>
                        <![CDATA[ technology ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Mon, 08 Apr 2019 15:47:03 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*9FSQFJgVw_Ip1a3E4rmmow.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Emmanuel Ohans</p>
<p>Early this year, the React team released a new addition, hooks, to React in version 16.8.0.</p>
<p>If React were a big bowl of candies, then hooks are the latest additions, very chewy candies with great taste!</p>
<p>So, what exactly do hooks mean? And why are they worth your time?</p>
<h3 id="heading-introduction">Introduction</h3>
<p>One of the main reasons hooks were added to React is to offer a more powerful and expressive way to write (and share) functionality between components.</p>
<blockquote>
<p>In the longer term, we expect Hooks to be the primary way people write React components — <a target="_blank" href="https://reactjs.org/docs/hooks-faq.html#should-i-use-hooks-classes-or-a-mix-of-both">React Team</a></p>
</blockquote>
<p>If hooks are going to be that important, why not learn about them in a fun way!</p>
<h3 id="heading-the-candy-bowl">The Candy Bowl</h3>
<p>Consider React to be a beautiful bowl of candy.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*u1Ubc4Zybc5AeACy38K08w.png" alt="Image" width="800" height="711" loading="lazy"></p>
<p>The bowl of candy has been incredibly helpful to people around the world.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*T-X_uzowaEqEDhRYkUfPvA.png" alt="Image" width="800" height="711" loading="lazy"></p>
<p>The people who made this bowl of candy realized that <strong>some</strong> of the candies in the bowl weren’t doing people much good.</p>
<p>A couple of the candies tasted great, yes! But they brought about some complexity when people ate them — think render props and higher order components?</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*9FSQFJgVw_Ip1a3E4rmmow.png" alt="Image" width="743" height="775" loading="lazy"></p>
<p>So, what did they do?</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*jahda3D5PnCmuyZOlqj5eA.png" alt="Image" width="800" height="732" loading="lazy"></p>
<p>They did the right thing — not throwing away all the previous candies, but making new sets of candies.</p>
<p>These candies were called <strong>Hooks</strong>.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*WqUVZyfDQX6ihazFZ21w_g.png" alt="Image" width="800" height="605" loading="lazy"></p>
<p>These candies exist for one purpose: <strong>to make it easier for you to do the things you were already doing</strong>.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*EG-OKgzmiZewSjEJ9l0y7Q.png" alt="Image" width="800" height="577" loading="lazy"></p>
<p>These candies aren’t super special. In fact, as you begin to eat them you’ll realize they taste familiar — they are just <strong>Javascript functions</strong>!</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*HRw5WfHH02tvoM13sDSfVA.png" alt="Image" width="800" height="672" loading="lazy"></p>
<p>As with all good candies, these <strong>10</strong> new candies all have their unique names. Though they are collectively called <strong>hooks</strong>.</p>
<p>Their names always begin with the three letter word, <em>use …</em> e.g. <code>useState</code>, <code>useEffect</code> etc.</p>
<p>Just like chocolate, these 10 candies all share some of the same ingredients. Knowing how one tastes, helps you relate to the other.</p>
<p>Sounds fun? Now let’s have these candies.</p>
<h3 id="heading-the-state-hook">The State Hook</h3>
<p>As stated earlier, hooks are functions. Officially, there are 10 of them. 10 new functions that exist to make writing and sharing functionalities in your components a lot more expressive.</p>
<p>The first hook we’ll take a look at is called, <code>useState</code>.</p>
<p>For a long time, you couldn’t use the local state in a functional component. Well, not until hooks.</p>
<p>With <code>useState</code>, your functional component can have (and update) local state.</p>
<p>How interesting.</p>
<p>Consider the following counter application:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*2909ks8DqBVC23n2Ykqe0Q.gif" alt="Image" width="652" height="326" loading="lazy"></p>
<p>With the <code>Counter</code> component shown below:</p>
<p>Simple, huh?</p>
<p>Let me ask you one simple question. Why exactly do we have this component as a Class component?</p>
<p>Well, the answer is simply because we need to keep track of some local state within the component.</p>
<p>Now, here’s the same component refactored to a functional component with access to state via the <code>useState</code> hooks.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*GxX7yyUGXJG2Kmf8CIG3aQ.gif" alt="Image" width="800" height="591" loading="lazy">
<em>Class to Hooks — wait for the animation.</em></p>
<p>What’s different?</p>
<p>I’ll walk you through it step by step.</p>
<p>A functional component doesn’t have all the <code>Class extend ...</code> syntax.</p>
<pre><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">CounterHooks</span>(<span class="hljs-params"></span>) </span>{  }
</code></pre><p>It also doesn’t require a <code>render</code> method.</p>
<pre><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">CounterHooks</span>(<span class="hljs-params"></span>) </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">h3</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"center"</span>&gt;</span>Welcome to the Counter of Life <span class="hljs-tag">&lt;/<span class="hljs-name">h3</span>&gt;</span>        <span class="hljs-tag">&lt;<span class="hljs-name">button</span>           <span class="hljs-attr">className</span>=<span class="hljs-string">"center-block"</span>           <span class="hljs-attr">onClick</span>=<span class="hljs-string">{this.handleClick}</span>&gt;</span> {count} <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>There are two concerns with the code above.</p>
<ol>
<li>You’re not supposed to use the <code>this</code> keyword in function components.</li>
<li>The <code>count</code> state variable hasn’t been defined.</li>
</ol>
<p>Extract <code>handleClick</code> to a separate function within the functional component:</p>
<pre><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">CounterHooks</span>(<span class="hljs-params"></span>) </span>{  <span class="hljs-keyword">const</span> handleClick = <span class="hljs-function">() =&gt;</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">h3</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"center"</span>&gt;</span>Welcome to the Counter of Life <span class="hljs-tag">&lt;/<span class="hljs-name">h3</span>&gt;</span>        <span class="hljs-tag">&lt;<span class="hljs-name">button</span>           <span class="hljs-attr">className</span>=<span class="hljs-string">"center-block"</span>           <span class="hljs-attr">onClick</span>=<span class="hljs-string">{handleClick}</span>&gt;</span> {count} <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>Before the refactor, the <code>count</code> variable came from the class component’s state object.</p>
<p>In functional components, and with hooks, that comes from invoking the <code>useState</code> function or hook.</p>
<p><code>useState</code> is called with one argument, the initial state value e.g. <code>useState(0)</code> where <code>0</code> represents the initial state value to be kept track of.</p>
<p>Invoking this function returns an array with two values.</p>
<pre><code><span class="hljs-comment">//? returns an array with 2 values. useState(0)</span>
</code></pre><p>The first value being the current state value being tracked, and second, a function to update the state value.</p>
<p>Think of this as some <code>state</code> and <code>setState</code> replica - however, they aren’t quite the same.</p>
<p>With this new knowledge, here’s <code>useState</code> in action.</p>
<pre><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">CounterHooks</span>(<span class="hljs-params"></span>) </span>{  <span class="hljs-comment">// ?   const [count, setCount] = useState(0);  const handleClick = () =&gt; {    setCount(count + 1)  }  return (      &lt;div&gt;        &lt;h3 className="center"&gt;Welcome to the Counter of Life &lt;/h3&gt;        &lt;button           className="center-block"           onClick={handleClick}&gt; {count} &lt;/button&gt;      &lt;/div&gt;    ); }</span>
</code></pre><p>There are a few things to note here, apart from the obvious simplicity of the code!</p>
<p>One, since invoking <code>useState</code> returns an array of values, the values could be easily destructed into separate values as shown below:</p>
<pre><code><span class="hljs-keyword">const</span> [count, setCount] = useState(<span class="hljs-number">0</span>);
</code></pre><p>Also, note how the <code>handleClick</code> function in the refactored code doesn’t need any reference to <code>prevState</code> or anything like that.</p>
<p>It just calls <code>setCount</code> with the new value <code>count + 1</code>.</p>
<pre><code>  <span class="hljs-keyword">const</span> handleClick = <span class="hljs-function">() =&gt;</span> {    setCount(count + <span class="hljs-number">1</span>) }
</code></pre><p>This is because of the correct value of the <code>count</code> state variable will always be kept across re-renders.</p>
<p>So, need to update count state variable, just call <code>setCount</code> with the new value e.g. <code>setCount(count + 1)</code></p>
<p>Simple as it sounds, you’ve built your very first component using hooks. I know it’s a contrived example, but that’s a good start!</p>
<p><strong>Nb</strong>: it’s also possible to pass a function to the state updater function. This is usually recommended as with class’ <code>setState</code> when a state update depends on a previous value of state e.g. <code>setCount(prevCount =&gt; prevCount +</code> 1)</p>
<h4 id="heading-multiple-usestate-calls">Multiple useState calls</h4>
<p>With class components, we all got used to set state values in an object whether they contained a single property or more.</p>
<pre><code><span class="hljs-comment">// single property state = {  count: 0}// multiple properties state = { count: 0, time: '07:00'}</span>
</code></pre><p>With <code>useState</code> you may have noticed a subtle difference.</p>
<p>In the example above, we only called <code>useState</code> with the actual initial value. Not an object to hold the value.</p>
<pre><code>useState(<span class="hljs-number">0</span>)
</code></pre><p>So, what if we wanted to another state value?</p>
<p>Can multiple <code>useState</code> calls be used?</p>
<p>Consider the component below. Same as before but this time it tracks time of click.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*E_BJDnVGUB8BLBs1tN2DKA.gif" alt="Image" width="714" height="377" loading="lazy"></p>
<p>As you can see, the hooks usage is quite the same, except for having a new <code>useState</code> call.</p>
<pre><code><span class="hljs-keyword">const</span> [time, setTime] = useState(<span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>())
</code></pre><p>Now <code>time</code> is used in the rendered <code>JSX</code> to retrieve the hour, minute and second of the click.</p>
<pre><code>&lt;p className=<span class="hljs-string">"center"</span>&gt;    at: { <span class="hljs-string">`<span class="hljs-subst">${time.getHours()}</span> : <span class="hljs-subst">${time.getMinutes()}</span> : <span class="hljs-subst">${time.getSeconds()}</span>`</span>}&lt;/p&gt;
</code></pre><p>Great!</p>
<p>However, is it possible to use an object with <code>useState</code> as opposed to multiple <code>useState</code> calls?</p>
<p>Absolutely!</p>
<p>If you choose to do this, you should note that unlike <code>setState</code> calls, the values passed into <code>useState</code> replaces the state value. <code>setState</code> merges object properties but <code>useState</code> replaces the entire value.</p>
<h3 id="heading-the-effect-hook">The Effect Hook</h3>
<p>With class components you’ve likely performed side effects such as logging, fetching data or managing subscriptions.</p>
<p>These side effects may be called “effects” for short, and the effect hook, <code>useEffect</code> was created for this purpose.</p>
<p>How’s it used?</p>
<p>Well, the <code>useEffect</code> hook is called by passing it a function within which you can perform your side effects.</p>
<p>Here’s a quick example.</p>
<pre><code>useEffect(<span class="hljs-function">() =&gt;</span> {  <span class="hljs-comment">// ? you can perform side effects here  console.log("useEffect first timer here.")})</span>
</code></pre><p>To <code>useEffect</code> I’ve passed an anonymous function with some side effect called within it.</p>
<p>The next logical question is, when is the <code>useEffect</code> function called?</p>
<p>Well, remember that in class components you had lifecycle methods such as <code>componentDidMount</code> and <code>componentDidUpdate</code>.</p>
<p>Since functional components don’t have these lifecycle methods, <code>useEffect</code> <em>kinda</em> takes their place.</p>
<p>Thus, in the example above, the function within <code>useEffect</code> also known as the effect function, will be invoked when the functional component mounts (<code>componentDidMount</code>) and when the component updates <code>componentDidUpdate</code>).</p>
<p>Here’s that in action.</p>
<p>By adding the <code>useEffect</code> call above to the counter app, here’s the behavior we get.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*0lmKYgp9IoA0ELj4Pfn7vw.gif" alt="Image" width="494" height="632" loading="lazy"></p>
<p><strong>NB</strong>: The <code>useEffect</code> hook isn’t entirely the same as <code>componentDidMount</code> + <code>componentDidUpdate</code>. It can be viewed as such, but the implementation differs with some subtle differences.</p>
<p>It’s interesting that the effect function was invoked every time there was an update. That’s great, but it’s not always the desired functionality.</p>
<p>What if you only want to run the effect function only when the component mounts?</p>
<p>That’s a common use case and <code>useEffect</code> takes a second parameter, an array of dependencies to handle this.</p>
<p>If you pass in an empty array, the effect function is run only on mount — subsequent re-renders don’t trigger the effect function.</p>
<pre><code>useEffect(<span class="hljs-function">() =&gt;</span> {    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"useEffect first timer here."</span>)}, [])
</code></pre><p><img src="https://cdn-media-1.freecodecamp.org/images/1*RsAP38Wj8zUihrVXNwKcsw.gif" alt="Image" width="510" height="582" loading="lazy"></p>
<p>If you pass any values into this array, then the effect function will be run on mount, and anytime the values passed are updated. i.e if any of the values are changed, the effected call will re-run.</p>
<pre><code>useEffect(<span class="hljs-function">() =&gt;</span> {    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"useEffect first timer here."</span>)}, [count])
</code></pre><p>The effect function will be run on mount, and whenever the count function changes.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*0lmKYgp9IoA0ELj4Pfn7vw.gif" alt="Image" width="494" height="632" loading="lazy">
<em>count changes when the button is clicked, so the effect function re-runs</em></p>
<p>What about subscriptions?</p>
<p>It’s common to subscribe and unsubscribe from certain effects in certain apps.</p>
<p>Consider the following:</p>
<pre><code>useEffect(<span class="hljs-function">() =&gt;</span> {  <span class="hljs-keyword">const</span> clicked = <span class="hljs-function">() =&gt;</span> <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'window clicked'</span>);  <span class="hljs-built_in">window</span>.addEventListener(<span class="hljs-string">'click'</span>, clicked);}, [])
</code></pre><p>In the effect above, upon mounting, a click event listener is attached to the window.</p>
<p>How do we unsubscribe from this listener when the component is unmounted?</p>
<p>Well, <code>useEffect</code> allows for this.</p>
<p>If you return a function within your effect function, it will be invoked when the component unmounts. This is the perfect place to cancel subscriptions as shown below:</p>
<pre><code>useEffect(<span class="hljs-function">() =&gt;</span> {    <span class="hljs-keyword">const</span> clicked = <span class="hljs-function">() =&gt;</span> <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'window clicked'</span>);    <span class="hljs-built_in">window</span>.addEventListener(<span class="hljs-string">'click'</span>, clicked);    <span class="hljs-keyword">return</span> <span class="hljs-function">() =&gt;</span> {      <span class="hljs-built_in">window</span>.removeEventListener(<span class="hljs-string">'click'</span>, clicked)    } }, [])
</code></pre><p>There’s a lot more you can do with the <code>useEffect</code> hook such as making API calls.</p>
<h3 id="heading-build-your-own-hooks">Build Your own Hooks</h3>
<p>From the start of this article we’ve taken (and used) candies from the candy box React provides.</p>
<p>However, React also provides a way for you to make your own unique candies — called custom hooks.</p>
<p>So, how does that work?</p>
<p>A custom hook is just a regular function. However, its name must begin with the word, <code>use</code> and if needed, it may call any of the React hooks within itself.</p>
<p>Below’s an example:</p>
<h3 id="heading-the-rules-of-hooks">The Rules of Hooks</h3>
<p>There are two rules to adhere to while using hooks.</p>
<ol>
<li>Only Call Hooks at the <a target="_blank" href="https://reactjs.org/docs/hooks-rules.html#only-call-hooks-at-the-top-level">Top Level</a> i.e. <em>not</em> within conditionals, loops or nested functions.</li>
<li>Only Call Hooks from React Functions i.e. Functional Components and Custom Hooks.</li>
</ol>
<p>This ESLint <a target="_blank" href="https://www.npmjs.com/package/eslint-plugin-react-hooks">plugin</a> is great to ensure you adhere to these rules within your projects.</p>
<h3 id="heading-other-candies">Other Candies</h3>
<p>We have considered a few of the hooks React provides, but there’s more!</p>
<p>This introduction should have prepared you to take on the perhaps more dense <a target="_blank" href="https://reactjs.org/docs/hooks-intro.html">documentation</a>. Also checkout my live editable react <a target="_blank" href="https://react-hooks-cheatsheet.com">hooks cheatsheet</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Let’s get hooked: a quick introduction to React Hooks ]]>
                </title>
                <description>
                    <![CDATA[ By Lekha Surasani Getting Started with React Hooks The React team introduced React Hooks to the world at React Conf in late October 2018. In early February 2019, they finally came in React v16.8.0. While I, like most others probably, won’t be able to... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/lets-get-hooked-a-quick-introduction-to-react-hooks-9e8bc3fbaeac/</link>
                <guid isPermaLink="false">66d46016a326133d12440a27</guid>
                
                    <category>
                        <![CDATA[ Front-end Development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ hooks ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                    <category>
                        <![CDATA[ react hooks ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tech  ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Mon, 01 Apr 2019 18:53:07 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*hwW04YcPNKdDmkmDaoaXDw.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Lekha Surasani</p>
<h4 id="heading-getting-started-with-react-hooks">Getting Started with React Hooks</h4>
<p>The React team introduced React Hooks to the world at React Conf in late October 2018. In early February 2019, they finally came in React v16.8.0. While I, like most others probably, won’t be able to use them in production for a while (until we decide to update React), I have been experimenting with them on the side.</p>
<p>I was actually so excited about it, I will be giving an intro talk about it at a local meetup. Additionally, I’ll be giving a talk about Hooks (and other upcoming React features) at WeRockITConf in Huntsville in May! (EDIT: I have now given these talks and you can find the presentations and the associated resources on <a target="_blank" href="https://lekhasurasani.com/speaking">my website</a>!) But for now, here’s how to get started with React Hooks!</p>
<h1 id="heading-what-are-hooks-anyway">What are Hooks anyway?</h1>
<p>React Hooks let you use state, and other React features without having to define a JavaScript class. It’s like being able to take advantage of the cleanliness and simplicity of a Pure Component <em>and</em> state and component lifecycle methods. This is because Hooks are just regular JavaScript functions! This lends itself to cleaner and less clunky code. A side by side comparison of what the code looks like with and without Hooks for a simple counting component:</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> <span class="hljs-string">'./App.css'</span>;
<span class="hljs-keyword">import</span> React, { useState } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-keyword">const</span> HooksExample = <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">const</span> [counter, 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> <span class="hljs-attr">className</span>=<span class="hljs-string">"App"</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">header</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"App-header"</span>&gt;</span>
                The button is pressed: { counter } times.
                <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(counter + 1)}
                    style={{ padding: '1em 2em', margin: 10 }}
                &gt;
                    Click me!
                <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">header</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
    )
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> HooksExample;
</code></pre>
<p>NoHooks.js:</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> <span class="hljs-string">'./App.css'</span>;
<span class="hljs-keyword">import</span> React, { Component } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-keyword">export</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">NoHooks</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Component</span> </span>{
    <span class="hljs-keyword">constructor</span>(props) {
        <span class="hljs-built_in">super</span>(props;
        <span class="hljs-built_in">this</span>.state = {
            <span class="hljs-attr">counter</span>: <span class="hljs-number">0</span>
        }
    }

    render() {
        <span class="hljs-keyword">const</span> { counter } = <span class="hljs-built_in">this</span>.state;
        <span class="hljs-keyword">return</span> (
            <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"App"</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">header</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"App-header"</span>&gt;</span>
                    The button is pressed: { counter } times.
                    <span class="hljs-tag">&lt;<span class="hljs-name">button</span>
                        <span class="hljs-attr">onClick</span>=<span class="hljs-string">{()</span> =&gt;</span> this.setState({ counter: counter + 1 }) }
                        style={{ padding: '1em 2em', margin: 10 }}
                    &gt;
                        Click me!
                    <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
                <span class="hljs-tag">&lt;/<span class="hljs-name">header</span>&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
        )    
    }
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> NoHooks;
</code></pre>
<p>Not only is the code a lot smaller — the saved space certainly adds up for larger components — it’s also a lot more <em>readable</em>, which is a huge advantage of Hooks. For beginners who are just getting started with React, it’s easier for them to read the first block of code and easily see exactly what’s happening. With the second block, we have some extraneous elements, and it’s enough to make you stop and wonder what it’s for.</p>
<p>Another great thing about hooks is that you can create your own! This means that a lot of the stateful logic we used to have to re-write from component to component, we can now abstract out to a custom hook — and <em>reuse it</em>.</p>
<p>The one example where this is particularly life-changing (for me) that comes to mind is use with forms. With all of the stateful logic of forms, it’s hard to reduce the size of the component. But now, with hooks, complex forms can become much simpler without the use of other form libraries.</p>
<p>But before we get to that, let’s take a look at the hook at hand — useState.</p>
<h1 id="heading-usestate">useState</h1>
<p>useState, as the name describes, is a hook that allows you to use state in your function. We define it as follows:</p>
<p>const [ someState, updateState ] = useState(initialState)</p>
<p>Let’s break this down:</p>
<ul>
<li><strong>someState:</strong> lets you access the current state variable, <em>someState</em></li>
<li><strong>updateState:</strong> function that allows you to update the state — whatever you pass into it becomes the new <em>someState</em></li>
<li><strong>initialState:</strong> what you want <em>someState</em> to be upon initial render</li>
</ul>
<p>(If you’re unfamiliar with array destructuring syntax, stop here and read <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Basic_variable_assignment">this</a>.)</p>
<p>Now that we understand the basic format of useState and how to call and use it, let’s go back to the example from before.</p>
<p>In this example<strong>, counter</strong> is the state variable, <strong>setCount</strong> is the updater function, and <strong>0</strong> is the initial state. We use <strong>setCount(counter + 1)</strong> to increment the count when the button is pressed, making <strong>counter + 1</strong> the new value of <strong>counter</strong>. Alternatively, if we wanted to use the previous state to update the current state, we could pass in the old state to setCount:</p>
<p><code>setCount(prevCount =&gt; prevCount + 1)</code></p>
<p>This is a simple example that isn’t reflective of what we’d normally use in an actual application. But let’s take a look at something we’re more likely to use — a simple sign-in form for email and password:</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> <span class="hljs-string">'./App.css'</span>;
<span class="hljs-keyword">import</span> React, { useState } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-keyword">const</span> LoginForm = <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">const</span> [email, setEmail] = useState(<span class="hljs-string">''</span>);
    <span class="hljs-keyword">const</span> [password, setPassword] = useState(<span class="hljs-string">''</span>);

    <span class="hljs-keyword">return</span> (
        <span class="hljs-keyword">const</span> { handleSubmit } = <span class="hljs-built_in">this</span>.props;
        <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"App"</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">header</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"App-header"</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">form</span> <span class="hljs-attr">onSubmit</span>=<span class="hljs-string">{handleSubmit}</span>&gt;</span>
                    <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">value</span>=<span class="hljs-string">{</span> <span class="hljs-attr">email</span> } <span class="hljs-attr">onChange</span>=<span class="hljs-string">{(e)</span> =&gt;</span> setEmail(e.target.value) } /&gt;
                    <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">value</span>=<span class="hljs-string">{</span> <span class="hljs-attr">password</span> } <span class="hljs-attr">onChange</span>=<span class="hljs-string">{(e)</span> =&gt;</span> setPassword(e.target.value) } /&gt;
                    <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"submit"</span>&gt;</span>Submit<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
                <span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">header</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
    )
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> LoginForm;
</code></pre>
<p>We have two separate state fields and state updaters. This allows us to create really simple forms without creating a whole JavaScript class.</p>
<p>If we wanted to simplify this further, we could create an object as the state. However, useState replaces the whole state instead of updating the object (as setState would), so we can replicate the usual behavior of setState as shown below:</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> <span class="hljs-string">'./App.css'</span>;
<span class="hljs-keyword">import</span> React, { useState } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-keyword">const</span> LoginForm = <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">const</span> [login, setLogin] = useState({ <span class="hljs-attr">email</span>: <span class="hljs-string">''</span>, <span class="hljs-attr">password</span>: <span class="hljs-string">''</span> });

    <span class="hljs-keyword">return</span> (
        <span class="hljs-keyword">const</span> { handleSubmit } = <span class="hljs-built_in">this</span>.props;
        <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"App"</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">header</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"App-header"</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">form</span> <span class="hljs-attr">onSubmit</span>=<span class="hljs-string">{handleSubmit}</span>&gt;</span>
                    <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">value</span>=<span class="hljs-string">{</span> <span class="hljs-attr">login.email</span> } <span class="hljs-attr">onChange</span>=<span class="hljs-string">{(e)</span> =&gt;</span> setLogin(prevState =&gt; { ...prevState, email: e.target.value }) } /&gt;
                    <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">value</span>=<span class="hljs-string">{</span> <span class="hljs-attr">login.password</span> } <span class="hljs-attr">onChange</span>=<span class="hljs-string">{(e)</span> =&gt;</span> setLogin(prevState =&gt; { ...prevState, password: e.target.value }) } /&gt;
                    <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"submit"</span>&gt;</span>Submit<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
                <span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">header</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
    )
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> LoginForm;
</code></pre>
<p>If you have state objects more complex than this, you would either want to break them out into separate states as in the first Login example, or use useReducer (we’ll get to that soon!).</p>
<p>So we’ve got state in hooks. What about component lifecycle methods?</p>
<h1 id="heading-useeffect">useEffect</h1>
<p>useEffect is another hook that handles componentDidUpdate, componentDidMount, and componentWillUnmount all in one call. If you need to fetch data, for example, you could useEffect to do so, as seen below.</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React, { useState, useEffect } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
<span class="hljs-keyword">import</span> axios <span class="hljs-keyword">from</span> <span class="hljs-string">'axios'</span>;
<span class="hljs-keyword">import</span> <span class="hljs-string">'./App.css'</span>;

<span class="hljs-keyword">const</span> HooksExample = <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">const</span> [data, setData] = useState();

    useEffect(<span class="hljs-function">() =&gt;</span> {
        <span class="hljs-keyword">const</span> fetchGithubData = <span class="hljs-keyword">async</span> (name) =&gt; {
            <span class="hljs-keyword">const</span> result = <span class="hljs-keyword">await</span> axios(<span class="hljs-string">`https://api.github.com/users/<span class="hljs-subst">${name}</span>/events`</span>)
            setData(result.data)
        }
        fetchGithubData(<span class="hljs-string">'lsurasani'</span>)
    }, [data])



    <span class="hljs-keyword">return</span> (
        <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"App"</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">header</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"App-header"</span>&gt;</span>
                {data &amp;&amp; (
                    data.map(item =&gt; <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>{item.repo.name}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>)
                )}
            <span class="hljs-tag">&lt;/<span class="hljs-name">header</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
    )
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> HooksExample;
</code></pre>
<p>Taking a look at useEffect we see:</p>
<ul>
<li>First argument: A function. Inside of it, we fetch our data using an async function and then set <strong>data</strong> when we get results.</li>
<li>Second argument: An array containing <strong>data</strong>. This defines when the component updates. As I mentioned before, useEffect runs when componentDidMount, componentWillUnmount, _and_componentDidUpdate would normally run. Inside the first argument, we’ve set some state, which would traditionally cause componentDidUpdate to run. As a result, useEffect would run again if we did not have this array. Now, useEffect will run on componentDidMount, componentWillUnmount, and if <strong>data</strong> was updated, componentDidUpdate. This argument can be empty— you can choose to pass in an empty array. In this case, only componentDidMount and componentWillUnmount will ever fire. But, you do have to specify this argument if you set some state inside of it.</li>
</ul>
<h1 id="heading-usereducer">useReducer</h1>
<p>For those of you who use Redux, useReducer will probably be familiar. useReducer takes in two arguments — a <strong>reducer</strong> and an <strong>initial state</strong>. A reducer is a function that you can define that takes in the current state and an “action”. The action has a type, and the reducer uses a switch statement to determine which block to execute based on the type. When it finds the correct block, it returns the state but with the modifications you define depending on the type. We can pass this reducer into useReducer, and then use this hook like this:</p>
<p><code>const [ state, dispatch ] = useReducer(reducer, initialState)</code></p>
<p>You use dispatch to say what action types you want to execute, like this:</p>
<p><code>dispatch({ type: name})</code></p>
<p>useReducer is normally used when you have to manage complex states — such as the signup form below.</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React, { useReducer } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-keyword">const</span> reducer = <span class="hljs-function">(<span class="hljs-params">state, action</span>) =&gt;</span> {
    <span class="hljs-keyword">switch</span> (action.type) {
        <span class="hljs-keyword">case</span> <span class="hljs-string">'firstName'</span>: {
            <span class="hljs-keyword">return</span> { ...state, <span class="hljs-attr">firstName</span>: action.value };
            }
        <span class="hljs-keyword">case</span> <span class="hljs-string">'lastName'</span>: {
            <span class="hljs-keyword">return</span> { ...state, <span class="hljs-attr">lastName</span>: action.value };
            }
        <span class="hljs-keyword">case</span> <span class="hljs-string">'email'</span>: {
            <span class="hljs-keyword">return</span> { ...state, <span class="hljs-attr">email</span>: action.value };
            }
        <span class="hljs-keyword">case</span> <span class="hljs-string">'password'</span>: {
            <span class="hljs-keyword">return</span> { ...state, <span class="hljs-attr">password</span>: action.value };
            }
        <span class="hljs-keyword">case</span> <span class="hljs-string">'confirmPassword'</span>: {
            <span class="hljs-keyword">return</span> { ...state, <span class="hljs-attr">confirmPassword</span>: action.value };
            }
        <span class="hljs-attr">default</span>: {
            <span class="hljs-keyword">return</span> state;
        }
    }
};

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">SignupForm</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">const</span> initialState = {
        <span class="hljs-attr">firstName</span>: <span class="hljs-string">''</span>,
        <span class="hljs-attr">lastName</span>: <span class="hljs-string">''</span>,
        <span class="hljs-attr">email</span>: <span class="hljs-string">''</span>,
        <span class="hljs-attr">password</span>: <span class="hljs-string">''</span>,
        <span class="hljs-attr">confirmPassword</span>: <span class="hljs-string">''</span>,
    }
    <span class="hljs-keyword">const</span> [formElements, dispatch] = useReducer(reducer, initialState);

    <span class="hljs-keyword">return</span> (
        <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"App"</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">header</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"App-header"</span>&gt;</span>
                <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">placeholder</span>=<span class="hljs-string">"First Name"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">{</span> <span class="hljs-attr">formElements.firstName</span>} <span class="hljs-attr">onChange</span>=<span class="hljs-string">{(e)</span> =&gt;</span> dispatch({ type: firstName, value: e.target.value }) } /&gt;
                    <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"Last Name"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">{</span> <span class="hljs-attr">formElements.lastName</span>} <span class="hljs-attr">onChange</span>=<span class="hljs-string">{(e)</span> =&gt;</span> dispatch({ type: lastName, value: e.target.value }) } /&gt;
                    <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"Email"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">{</span> <span class="hljs-attr">formElements.email</span>} <span class="hljs-attr">onChange</span>=<span class="hljs-string">{(e)</span> =&gt;</span> dispatch({ type: email, value: e.target.value }) } /&gt;
                    <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"Password"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">{</span> <span class="hljs-attr">formElements.password</span>} <span class="hljs-attr">onChange</span>=<span class="hljs-string">{(e)</span> =&gt;</span> dispatch({ type: password, value: e.target.value }) } /&gt;
                    <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"Confirm Password"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">{</span> <span class="hljs-attr">formElements.confirmPassword</span>} <span class="hljs-attr">onChange</span>=<span class="hljs-string">{(e)</span> =&gt;</span> dispatch({ type: confirmPassword, value: e.target.value }) } /&gt;
                <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">header</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
    );
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> SignupForm;
</code></pre>
<p>This hook has a lot of additional applications, including allowing us to specify a few reducers throughout our application and then reusing them for each of our components, changing based on what happens in those components. On a high level, this is similar to Redux’s functionality — so we may be able to avoid using Redux for relatively simpler applications.</p>
<h1 id="heading-custom-hooks">Custom Hooks</h1>
<p>So we’ve covered 3 basic hooks — let’s look at how to make our own. Remember the example I mentioned earlier with the login form? Here it is again as a reminder:</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> <span class="hljs-string">'./App.css'</span>;
<span class="hljs-keyword">import</span> React, { useState } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-keyword">const</span> LoginForm = <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">const</span> [email, setEmail] = useState(<span class="hljs-string">''</span>);
    <span class="hljs-keyword">const</span> [password, setPassword] = useState(<span class="hljs-string">''</span>);

    <span class="hljs-keyword">return</span> (
        <span class="hljs-keyword">const</span> { handleSubmit } = <span class="hljs-built_in">this</span>.props;
        <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"App"</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">header</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"App-header"</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">form</span> <span class="hljs-attr">onSubmit</span>=<span class="hljs-string">{handleSubmit}</span>&gt;</span>
                    <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">value</span>=<span class="hljs-string">{</span> <span class="hljs-attr">email</span> } <span class="hljs-attr">onChange</span>=<span class="hljs-string">{(e)</span> =&gt;</span> setEmail(e.target.value) } /&gt;
                    <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">value</span>=<span class="hljs-string">{</span> <span class="hljs-attr">password</span> } <span class="hljs-attr">onChange</span>=<span class="hljs-string">{(e)</span> =&gt;</span> setPassword(e.target.value) } /&gt;
                    <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"submit"</span>&gt;</span>Submit<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
                <span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">header</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
    )
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> LoginForm;
</code></pre>
<p>We useState for both and define a state variable and an updater function for both of the fields. What if we could simplify this further? Here’s a custom hook for handling any kind of input value changes (note: the convention for naming a custom hooks is: use).</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> { useState } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> useInputValue = <span class="hljs-function">(<span class="hljs-params">initial</span>) =&gt;</span> {
    <span class="hljs-keyword">const</span> [value, setValue] = useState(initial)
    <span class="hljs-keyword">return</span> { value, <span class="hljs-attr">onChange</span>: <span class="hljs-function"><span class="hljs-params">e</span> =&gt;</span> setValue(e.target.value) }
}
</code></pre>
<p>We use useState to handle the changes as we did in the previous example, but this time we return the value and an onChange function to update that value. So, the login form can now look like this:</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
<span class="hljs-keyword">import</span> { useInputValue } <span class="hljs-keyword">from</span> <span class="hljs-string">'./Custom'</span>

<span class="hljs-keyword">const</span> Form = <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">const</span> email = useInputValue(<span class="hljs-string">''</span>)
    <span class="hljs-keyword">const</span> password = useInputValue(<span class="hljs-string">''</span>)

    <span class="hljs-keyword">return</span> (
        <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"App"</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">header</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"App-header"</span>&gt;</span>
                <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">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"Email"</span> {<span class="hljs-attr">...email</span>} /&gt;</span>
                <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
                <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">type</span>=<span class="hljs-string">"password"</span> <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"Password"</span> {<span class="hljs-attr">...password</span>} /&gt;</span>
                <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">header</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
    );
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> Form;
</code></pre>
<p>We initialize useInputValue with an empty string for both of our fields, and set the result to the name of the field. We can put this back in the input element so the input element renders the value and onChange functions dynamically.</p>
<p>Now, we’ve made this form even simpler — and our custom hook can be reused wherever we need a form input element!</p>
<p>I think that this is one of the most useful things about hooks — the ability to make your own and allow for this previously stateful logic that was locked inside each component to be taken out and reused, allowing for each component to become simpler.</p>
<p>So we’ve gone over: useState, useEffect, useReducer, and finally, custom hooks. There’s a few basic things that we haven’t gone over just yet — namely, the two general rules to follow with Hooks:</p>
<ol>
<li><strong>Only call Hooks at the <em>top level</em></strong> <em>—</em> Not in loops, nested functions, conditions, etc. This ensures that hooks are always called in the same order after each render. This is important because React relies on the order that Hooks are called to determine which state corresponds to a useState call (if you are using multiple). If one of your hooks is hidden in a loop, nested function, or a conditional, the order can change from render to render, messing up which state corresponds to which useState.</li>
<li><strong>Only call Hooks from React functions or custom hooks</strong> — In other words, don’t call Hooks from JavaScript functions.</li>
</ol>
<p>Hopefully this clears up how and when to use hooks for you! Some additional resources you can take a look at:</p>
<ul>
<li><a target="_blank" href="https://reactjs.org/docs/hooks-intro.html">The React docs</a></li>
<li><a target="_blank" href="https://github.com/rehooks/awesome-react-hooks">Collection of Hooks resources</a></li>
</ul>
<p>If you have any questions/comments, please feel free to ask below!</p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
