<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Joseph Chow</title>
    <description>The latest articles on Forem by Joseph Chow (@chowjiaming).</description>
    <link>https://forem.com/chowjiaming</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F162247%2F2e591319-e1df-4f24-8897-5604eb480478.jpeg</url>
      <title>Forem: Joseph Chow</title>
      <link>https://forem.com/chowjiaming</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/chowjiaming"/>
    <language>en</language>
    <item>
      <title>Value Types vs Reference types in JavaScript Explained</title>
      <dc:creator>Joseph Chow</dc:creator>
      <pubDate>Mon, 18 Jan 2021 00:53:08 +0000</pubDate>
      <link>https://forem.com/chowjiaming/value-types-vs-reference-types-in-javascript-explained-kmn</link>
      <guid>https://forem.com/chowjiaming/value-types-vs-reference-types-in-javascript-explained-kmn</guid>
      <description>&lt;p&gt;When storing a variable in JavaScript, the JavaScript engine may store it as one of two types of values: a &lt;em&gt;primitive&lt;/em&gt; or &lt;em&gt;reference&lt;/em&gt; value. Understanding the difference in how they behave will help to avoid mistakes while manipulating them.&lt;/p&gt;

&lt;h2&gt;
  
  
  An Example
&lt;/h2&gt;

&lt;p&gt;Instead of jumping straight into a boring explaination, consider this script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const firstList = ['A', 'B', 'C'];
const secondList = firstList;
secondList.push('D');
console.log('firstList:', firstList);
console.log('secondList:', secondList);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We may expect the output to be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"firstList:" ['A', 'B', 'C'];
"secondList:" ['A', 'B', 'C', 'D'];
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But instead, we get an output of:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"firstList:" ['A', 'B', 'C', 'D'];
"secondList:" ['A', 'B', 'C', 'D'];
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What Happened
&lt;/h2&gt;

&lt;p&gt;This is because of how JavaScript treats arrays in memory. Arrays are stored as a &lt;em&gt;reference value&lt;/em&gt;, so JavaScript will only copy the reference to that point in memory. This means that to the original array and not the value of the array.&lt;/p&gt;

&lt;p&gt;Diving deeper, when accessing the varible as a primitive value, you are manipulating the actual value stored of that variable. In other words, the variable that is assigned a primitive value is accessed by value.&lt;/p&gt;

&lt;p&gt;Unlike storing a primitive value, when you create an object, you are accessing the reference of that object in memory, rather than the actual value of that object. In other words, it means a variable that is assigned an object is accessed by reference.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fixing our Example
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;spread operator&lt;/strong&gt; will create a new &lt;em&gt;reference value&lt;/em&gt; in memory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const firstList = ['A', 'B', 'C'];
const secondList = [...firstList];
secondList.push('D');
console.log('firstList:', firstList); // "firstList:" ['A', 'B', 'C'];
console.log('secondList:', secondList); // "secondList:" ['A', 'B', 'C', 'D'];
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In ES5, you could copy an array into a new &lt;em&gt;reference value&lt;/em&gt; with the &lt;strong&gt;slice&lt;/strong&gt; method.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const firstList = ['A', 'B', 'C'];
const secondList = firstList.slice();
secondList.push('D');
console.log('firstList:', firstList); // "firstList:" ['A', 'B', 'C'];
console.log('secondList:', secondList); // "secondList:" ['A', 'B', 'C', 'D'];
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, the &lt;strong&gt;slice&lt;/strong&gt; method cannot be used to create &lt;strong&gt;sparse arrays&lt;/strong&gt; or arrays with 'holes' in them.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let array = [];
array[2] = 2;
array[4] = 4;

console.log(array.slice()); // [empty × 2, 2, empty, 4]
console.log(...array); // undefined undefined 2 undefined 4

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Diving Deeper
&lt;/h2&gt;

&lt;p&gt;Javascript has six data types that values are assigned as primative type: Boolean, null, undefined, String, Number, and Symbol. Like mentioned above, the values in primative types are accessed only by value, so they can be copied by value. The values can be copied and changed with no relation to each other.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let a = true;
let b = 'hello';
let x = a;
let y = b;
console.log(x, y, a, b); // true, 'hello', true, 'hello'
x = null;
y = undefined;
console.log(x, y, a, b); // null, undefined, true, 'hello'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Arrays, Functions, and Objects are all derived from object contructors in JavaScript. An explaination for this can be found &lt;a href="https://github.com/getify/You-Dont-Know-JS/blob/1st-ed/this%20%26%20object%20prototypes/ch3.md"&gt;here&lt;/a&gt;. The important thing to understand is that objects are passed by &lt;em&gt;reference value&lt;/em&gt;. Like mentioned above, a varible assigned an object only knows is the location of the object in memory, not the object itself. Here is an example of a common bug that occurs when working with objects:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let vehicleOne = {
  seats: 2,
  airConditioning: true
};
let vehicleTwo = vehicleOne;
vehicleOne.color = 'red';
console.log(vehicleOne.color); // 'red'
console.log(vehicleTwo.color); // 'red'

vehicleTwo = {...vehicleOne};
vehicleOne.color = 'white';
console.log(vehicleOne.color); // 'white'
console.log(vehicleTwo.color); // 'red'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By using the '=' operator, we only assigned &lt;strong&gt;vehicleTwo&lt;/strong&gt; the reference to the object, so any changes made to the &lt;strong&gt;vehicleOne&lt;/strong&gt; object will alter the same spot in memory that &lt;strong&gt;vehicleTwo&lt;/strong&gt; is assigned. Once again, we used the &lt;strong&gt;spread operator&lt;/strong&gt; to copy and create a new &lt;em&gt;reference value&lt;/em&gt; for &lt;strong&gt;vehicleTwo&lt;/strong&gt; to avoid this error. This is why objects are known to be &lt;strong&gt;mutable&lt;/strong&gt; in JavaScript. &lt;/p&gt;

&lt;p&gt;This is also why you need to treat state in React as immutable, because the &lt;em&gt;reference value&lt;/em&gt; will not change if you try and manipulate the state directly. You can read more about treating state as being immutable in React &lt;a href="https://www.freecodecamp.org/news/handling-state-in-react-four-immutable-approaches-to-consider-d1f5c00249d5/"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Deep Copying
&lt;/h2&gt;

&lt;p&gt;Both times we used the &lt;strong&gt;spread operator&lt;/strong&gt;, it managed to create us a &lt;em&gt;reference value&lt;/em&gt; for a new object. However, there is a catch. Consider this script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const bookOne = {
  title: 'Primative Types vs Reference Values in JavaScript',
  pages: 50,
  info: {
    name: 'Joseph',
    publication: 'dev.to'
  }
}

const bookTwo = { ...bookOne }


bookTwo.title = 'Immutability in JavaScript';
bookTwo.info.publication = 'medium.com';

console.log('Book One title:', bookOne.title); // 'Primative Types vs Reference Values in JavaScript'
console.log('Book One authors:', bookOne.info.publication); // 'dev.to'

console.log('Book Two:', bookTwo.title); // 'Immutability in JavaScript'
console.log('Book Two:', bookTwo.info.publication); // 'dev.to'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Only the title of &lt;strong&gt;bookTwo&lt;/strong&gt; changed. If one of the elements is another &lt;em&gt;reference value&lt;/em&gt; to another object, all it would do is make a copy of the &lt;em&gt;reference value&lt;/em&gt; into memory and it will not change what it’s referenced to. &lt;a href="https://blog.logrocket.com/methods-for-deep-cloning-objects-in-javascript/"&gt;Here&lt;/a&gt; is a great article for further reading into how to deep copy objects in JavaScript.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>How to setup LESS with React without Ejecting</title>
      <dc:creator>Joseph Chow</dc:creator>
      <pubDate>Sun, 10 Jan 2021 18:04:24 +0000</pubDate>
      <link>https://forem.com/chowjiaming/how-to-setup-less-with-react-without-ejecting-1nej</link>
      <guid>https://forem.com/chowjiaming/how-to-setup-less-with-react-without-ejecting-1nej</guid>
      <description>&lt;p&gt;&lt;strong&gt;SASS&lt;/strong&gt; has been natively supported since React 16.7 with a single additional package &lt;strong&gt;node-sass&lt;/strong&gt;. It can be easily integrated simply by adding &lt;strong&gt;node-sass&lt;/strong&gt; and importing your pre-processed stylesheet.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// package.json

"dependencies": {
   "node-sass": "^5.0.0"
 }
...

// App.js

@import 'stylesheet.scss'

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, there is not such an easy solution to handle compiling &lt;strong&gt;LESS&lt;/strong&gt; stylesheets. This is problematic because to manually configure webpack to compile our &lt;strong&gt;LESS&lt;/strong&gt; stylesheets requires us to eject from the default &lt;strong&gt;create-react-app&lt;/strong&gt; configuration. &lt;/p&gt;

&lt;p&gt;Ejecting is an irreversible process that can add frustrations in development down the line. You can alternatively use a package like &lt;strong&gt;react-app-rewired&lt;/strong&gt; to slightly modify the webpack configs, but that requires rewiring all your run react scripts, and additionally, there may be unforeseen side effects down the line. That is a lot just to use &lt;strong&gt;LESS&lt;/strong&gt; stylesheets in your app.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Stuff can break. - &lt;a href="https://twitter.com/dan_abramov/status/1045809734069170176?lang=en"&gt;Dan Abramov&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So, if we decide to use &lt;strong&gt;LESS&lt;/strong&gt; stylesheets in our app, let us see how to set it up with your react app, without having to eject from &lt;strong&gt;create-react-app&lt;/strong&gt; and modifying your webpack config manually. &lt;/p&gt;

&lt;p&gt;You can take a look at the completed boilerplate setup &lt;a href="https://github.com/joefstack/cra-less-starter"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installing Our Packages
&lt;/h2&gt;

&lt;p&gt;Let us begin with creating a new &lt;strong&gt;create-react-app&lt;/strong&gt; project.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx create-react-app less-boilerplate-demo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We will be implementing our compiler to watch the &lt;strong&gt;LESS&lt;/strong&gt; file in our directory to export to our desired output directory. So each time our &lt;strong&gt;LESS&lt;/strong&gt; file changes, the updates will reflect in real time for ease of development. We will first start by installing our packages for less and our compiler as dev dependencies.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install less less-watch-compiler concurrently --save-dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Setting up LESS Watcher Config
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;less-watcher-compiler&lt;/strong&gt; package takes a json file for configuration. Create a json file called less-watcher.config.json in our base directory. It can be setup to watch the relevant directories for edits and output directories to compile into. &lt;/p&gt;

&lt;p&gt;In this demo, we are just working with the base &lt;strong&gt;create-react-app&lt;/strong&gt; boilerplate directories. So we will be watching our &lt;strong&gt;src&lt;/strong&gt; directory and outputting back into the &lt;strong&gt;src&lt;/strong&gt;. However, you can modify your config json file to input and output to match your project file structure. For more information, check out the &lt;a href="https://www.npmjs.com/package/less-watch-compiler"&gt;docs&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// less-watcher.config.json

{
  "watchFolder": "src/",
  "outputFolder": "src/",
  "sourceMap": true,
  "runOnce": false,
  "enableJs": true
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For this demo, I will be adding an &lt;strong&gt;App.less&lt;/strong&gt; directly into my &lt;strong&gt;src&lt;/strong&gt; folder and changing two color variables to test the compiler.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// App.less

@app-primary: #0f3460;
@app-secondary: #e94560;

.App {
  text-align: center;
}

.App-logo {
  animation: App-logo-spin infinite 20s linear;
  height: 40vmin;
}

.App-header {
  background-color: @app-primary;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  font-size: calc(10px + 2vmin);
  color: white;
}

.App-link {
  color: @app-secondary;
}

@keyframes App-logo-spin {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Setting up Project Scripts
&lt;/h2&gt;

&lt;p&gt;We want to run the compiler when we run our app start script in development. So let us install the &lt;strong&gt;concurrently&lt;/strong&gt; package as a dev dependency so that we can run our compile script together with &lt;strong&gt;react-scripts&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install concurrently --save-dev

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, let us modify our start script in our &lt;strong&gt;package.json&lt;/strong&gt; to run run our less compiler based on our configuration file when starting our development server.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// package.json

...

  "scripts": {
    "start": "concurrently --kill-others \"less-watch-compiler --config less-watcher.config.json\" \"react-scripts start\"",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },

...

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Congratulations!!
&lt;/h2&gt;

&lt;p&gt;Now, when you run &lt;strong&gt;npm start&lt;/strong&gt; you can make modifications to your less stylesheet file and see your edits in your app upon saving your file. If you want to take a look at the complete code, or create your own fork, check out my repo &lt;a href="https://github.com/joefstack/cra-less-starter"&gt;here&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>react</category>
      <category>webdev</category>
      <category>css</category>
      <category>less</category>
    </item>
    <item>
      <title>Creating Resilient Components with useMemo</title>
      <dc:creator>Joseph Chow</dc:creator>
      <pubDate>Mon, 04 Jan 2021 23:54:50 +0000</pubDate>
      <link>https://forem.com/chowjiaming/creating-reusable-components-with-usememo-ikb</link>
      <guid>https://forem.com/chowjiaming/creating-reusable-components-with-usememo-ikb</guid>
      <description>&lt;p&gt;Today we will looking at a principle of creating resilient components in React and creating a useful custom hook with the &lt;strong&gt;useMemo&lt;/strong&gt; hook. Sometimes when creating a component, we can assume that it will only be used once. &lt;/p&gt;

&lt;p&gt;However, that assumption may lead into problems sharing props when reusing a simple component. In our example here today, we will look at creating a resilient form component.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Sometimes we assume a certain component is only ever displayed once. Such as a navigation bar. This might be true for some time. However, this assumption often causes design problems that only surface much later. - &lt;a href="https://overreacted.io/writing-resilient-components/" rel="noopener noreferrer"&gt;Dan Abramov&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You can check out the completed code to follow along &lt;a href="https://github.com/joefstack/usememo-unique-ids" rel="noopener noreferrer"&gt;here&lt;/a&gt; and the demo in action &lt;a href="https://usememo-unique-ids.netlify.app/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Setup
&lt;/h2&gt;

&lt;p&gt;We will start by bootstrapping a project with &lt;strong&gt;create-react-app&lt;/strong&gt; and installing the &lt;strong&gt;react-bootstrap&lt;/strong&gt; and &lt;strong&gt;shortid&lt;/strong&gt; packages. I will be using the &lt;strong&gt;shortid&lt;/strong&gt; package in this demo to create our randomly generated unique IDs, but you can use any method you like to create a random ID string.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx create-react-app usememo-resilient-components;
cd usememo-resilient-components;
npm i react-boostrap shortid;
npm start;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Don't forget to add the CDN link for the bootstrap css files as &lt;strong&gt;react-bootstrap&lt;/strong&gt; does not include them. You can follow the &lt;strong&gt;react-bootstrap&lt;/strong&gt; docs &lt;a href="https://react-bootstrap.github.io/getting-started/introduction" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// index.html

...
&amp;lt;link
  rel="stylesheet"
  href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css"
  integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk"
  crossorigin="anonymous"
/&amp;gt;
...

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Creating the form handler
&lt;/h2&gt;

&lt;p&gt;Let's start by going into our App.js, clearing out the boilerplate, and creating our form handler. We will set an empty object using the &lt;strong&gt;useState&lt;/strong&gt; hook to store our parameters. To maximize modularity, in our form handler function we will pass a callback to setParams that target the name and value attributes of as many form elements as necessary. &lt;/p&gt;

&lt;p&gt;Also, let's import some bootstrap elements from our &lt;strong&gt;react-bootstrap&lt;/strong&gt; package and set the container and column to display for now. Your &lt;strong&gt;App.js&lt;/strong&gt; should look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// App.js

import { useState } from "react";
import { Container, Col } from "react-bootstrap";

function App() {
  const [params, setParams] = useState({});
  const handleChange = (e) =&amp;gt; {
    const param = e.target.name;
    const value = e.target.value;
    setParams((prevParams) =&amp;gt; {
      return { ...prevParams, [param]: value };
    });
  };

  return (
    &amp;lt;Container&amp;gt;
      &amp;lt;Col lg="5"&amp;gt;
        &amp;lt;h1&amp;gt;Generate Unique IDs Demo&amp;lt;/h1&amp;gt;
      &amp;lt;/Col&amp;gt;
    &amp;lt;/Container&amp;gt;
  );
}

export default App;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Creating our form and displaying the input
&lt;/h2&gt;

&lt;p&gt;Next, create we will create our form component. For this demo, I have imported a basic two element form from &lt;strong&gt;react-bootstrap&lt;/strong&gt;, but feel free to add as many form elements as you want. Our component will be passed our handler function as a prop from &lt;strong&gt;App.js&lt;/strong&gt; to handle our form onChange attribute.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// InputForm.js

import { Form } from "react-bootstrap";

export default function InputForm({ handleChange }) {
  return (
    &amp;lt;Form className="mb-2"&amp;gt;
      &amp;lt;Form.Group&amp;gt;
        &amp;lt;Form.Label&amp;gt;Email&amp;lt;/Form.Label&amp;gt;
        &amp;lt;Form.Control
          type="email"
          placeholder="Enter email"
          name="email"
          onChange={handleChange}
        /&amp;gt;
      &amp;lt;/Form.Group&amp;gt;
      &amp;lt;Form.Group&amp;gt;
        &amp;lt;Form.Label&amp;gt;Name&amp;lt;/Form.Label&amp;gt;
        &amp;lt;Form.Control
          type="text"
          placeholder="Enter Name"
          name="name
          onChange={handleChange}
        /&amp;gt;
      &amp;lt;/Form.Group&amp;gt;
    &amp;lt;/Form&amp;gt;
  );
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To see what our returned parameters are in state, we could simply log them to our console, but I have created a component to display our parameters on our page for this demo. My component will map through all of the parameters passed from our form handler in &lt;strong&gt;App.js&lt;/strong&gt; and display them in a Jumbotron element.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// DisplayInput.js

...

import React from "react";
import { Jumbotron } from "react-bootstrap";

export default function DisplayInput({ params }) {
  const paramKeys = Object.keys(params);
  return (
    &amp;lt;Jumbotron&amp;gt;
      {paramKeys.map((key) =&amp;gt; {
        return &amp;lt;p key={key}&amp;gt;{key + ": " + params[key]}&amp;lt;/p&amp;gt;;
      })}
    &amp;lt;/Jumbotron&amp;gt;
  );
}

...

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we can import both elements into our &lt;strong&gt;App.js&lt;/strong&gt; and pass the handler to our form component and pass our parameters in state to our display component.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// App.js
...

import DisplayInput from "./Components/DisplayInput";
import InputForm from "./Components/InputForm";

...

return (
  &amp;lt;Container&amp;gt;
    &amp;lt;Col lg="5"&amp;gt;
      &amp;lt;h1&amp;gt;Generate Unique IDs Demo&amp;lt;/h1&amp;gt;
      &amp;lt;InputForm handleChange={handleChange} /&amp;gt;
      &amp;lt;DisplayInput params={params} /&amp;gt;
    &amp;lt;/Col&amp;gt;
  &amp;lt;/Container&amp;gt;
);

...

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When you run &lt;strong&gt;npm start&lt;/strong&gt;, you should be able to see our the name and value of our inputs displayed in our Jumbotron.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F2a7attjbcu5fvij73m8t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F2a7attjbcu5fvij73m8t.png" alt="Single Component Input Display"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;This becomes problematic when you want to reuse the same form component again with the same handler. In our &lt;strong&gt;App.js&lt;/strong&gt;, let's render our form component again.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// App.js

...

return (
  &amp;lt;Container&amp;gt;
    &amp;lt;Col lg="5"&amp;gt;
      &amp;lt;h1&amp;gt;Generate Unique IDs Demo&amp;lt;/h1&amp;gt;
      &amp;lt;InputForm handleChange={handleChange} /&amp;gt;
      &amp;lt;InputForm handleChange={handleChange} /&amp;gt;
      &amp;lt;DisplayInput params={params} /&amp;gt;
    &amp;lt;/Col&amp;gt;
  &amp;lt;/Container&amp;gt;
);
...

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can see in the figure below that our parameters prop will not distinguish between our inputs from both form components:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fe504e0upjx9uh144237p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fe504e0upjx9uh144237p.png" alt="Multiple Component Display Problem"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We could solve this issue with writing a separate form handler function. But let's say that you want to use the form component multiple more times. You would have to create a separate function to pass to each form. &lt;/p&gt;

&lt;h2&gt;
  
  
  Creating a custom useMemo hook
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;useMemo&lt;/strong&gt; is a hook included in react that returns a memoized value. This means that it will only fire if one of its dependencies changes. This means that it will not recalculate methods that are computationally expensive upon each re-render, if its passed values do not change. You can read more about it in the react hooks docs &lt;a href="https://reactjs.org/docs/hooks-reference.html#usememo" rel="noopener noreferrer"&gt;here&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Under a new directory, we will create our custom &lt;strong&gt;useUniqueId.js&lt;/strong&gt; hook file. We will create a variable and pass &lt;strong&gt;useMemo&lt;/strong&gt; our id generator function and an empty array. Like with the &lt;strong&gt;useEffect&lt;/strong&gt; hook, the empty array will tell &lt;strong&gt;useMemo&lt;/strong&gt; to only fire once per component render. Lastly, our hook will return generated unique id with our element name suffix.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// useUniqueId.js

...

import { useMemo } from "react";
const shortid = require("shortid");

const useUniqueId = () =&amp;gt; {
  const uniqueId = useMemo(() =&amp;gt; shortid.generate(), []);
  return (elementNameSuffix) =&amp;gt; `${uniqueId}_${elementNameSuffix}`;
};

export default useUniqueId;

...

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we can import our custom &lt;strong&gt;useUniqueId&lt;/strong&gt; hook into our form component and pass it to our name attributes in the form elements.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// useUniqueId.js

...

import { Form } from "react-bootstrap";
import useUniqueId from "../helpers/useUniqueId";

export default function InputForm({ handleChange }) {
  const generateId = useUniqueId();
  return (
    &amp;lt;Form className="mb-2"&amp;gt;
      &amp;lt;Form.Group&amp;gt;
        &amp;lt;Form.Label&amp;gt;Email&amp;lt;/Form.Label&amp;gt;
        &amp;lt;Form.Control
          type="email"
          placeholder="Enter email"
          name={generateId("email")}
          onChange={handleChange}
        /&amp;gt;
      &amp;lt;/Form.Group&amp;gt;
      &amp;lt;Form.Group&amp;gt;
        &amp;lt;Form.Label&amp;gt;Name&amp;lt;/Form.Label&amp;gt;
        &amp;lt;Form.Control
          type="text"
          placeholder="Enter Name"
          name={generateId("name")}
          onChange={handleChange}
        /&amp;gt;
      &amp;lt;/Form.Group&amp;gt;
    &amp;lt;/Form&amp;gt;
  );
}

...

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, let's run our app again and see the result. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fj0m5rqwoa838t626vwvq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fj0m5rqwoa838t626vwvq.png" alt="Multiple Component Unique Parameters"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see, now our parameters can be distinguished uniquely from each other, no matter how many times we render our form component!&lt;/p&gt;

&lt;h2&gt;
  
  
  Congratulations!!
&lt;/h2&gt;

&lt;p&gt;We now our form components can be rendered multiple times without having to worry about our parameters being lost and overwritten. Our custom hook can also be used on any attribute in any component that you want to re-use.&lt;/p&gt;

&lt;p&gt;You can check out the completed code &lt;a href="https://github.com/joefstack/usememo-unique-ids" rel="noopener noreferrer"&gt;here&lt;/a&gt; and the demo in action &lt;a href="https://usememo-unique-ids.netlify.app/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Handling multi-page API calls with React Hooks</title>
      <dc:creator>Joseph Chow</dc:creator>
      <pubDate>Wed, 30 Dec 2020 19:09:25 +0000</pubDate>
      <link>https://forem.com/chowjiaming/handling-multi-page-api-calls-with-react-hooks-19jd</link>
      <guid>https://forem.com/chowjiaming/handling-multi-page-api-calls-with-react-hooks-19jd</guid>
      <description>&lt;p&gt;Today we will be walking through an example of how to make continuous API calls to fetch multiple pages of data. Our goal is to build a small web app using React and the HooksAPI that will load dynamically based on user parameters. &lt;/p&gt;

&lt;p&gt;We will be fetching data from the free API &lt;a href="https://apidocs.cheapshark.com/"&gt;CheapShark API&lt;/a&gt;, which provides data for sales across multiple game vendors. &lt;strong&gt;CheapShark&lt;/strong&gt; returns data on a page by page basis, so multiple API calls will have to be made to fetch results when there is more than one page of results returned.&lt;/p&gt;

&lt;p&gt;You can check out the completed demo project &lt;a href="https://search-steam-sales.netlify.app/"&gt;here&lt;/a&gt; and the completed code &lt;a href="https://github.com/joefstack/react-steam-sales"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  App Overview
&lt;/h2&gt;

&lt;p&gt;Our demo app will allow users to take in three parameters for searching through game deals. You can see in the &lt;strong&gt;CheapShark API&lt;/strong&gt; &lt;a href="(https://apidocs.cheapshark.com/)"&gt;docs&lt;/a&gt; which parameters can be taken in. We will be using &lt;a href="https://www.npmjs.com/package/axios"&gt;Axios&lt;/a&gt; to fetch the data and the &lt;strong&gt;Reach Hooks API&lt;/strong&gt; to handle user actions. &lt;/p&gt;

&lt;p&gt;You can try an example of what the &lt;strong&gt;CheapShark API&lt;/strong&gt; returns in an example call here: &lt;a href="https://www.cheapshark.com/api/1.0/deals?storeID=1&amp;amp;upperPrice=15&amp;amp;pageSize=5"&gt;https://www.cheapshark.com/api/1.0/deals?storeID=1&amp;amp;upperPrice=15&amp;amp;pageSize=5&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;The API returns all the deals it can find with a price under 15 dollars, but without a page number parameter and a maximum page size of 5, it only returns one page of results. We will see how to handle getting all the results through pagination below.&lt;/p&gt;

&lt;h2&gt;
  
  
  Initial Project Setup
&lt;/h2&gt;

&lt;p&gt;So let's begin with the basic create-react-app boilerplate and install the &lt;a href="https://www.npmjs.com/package/axios"&gt;axios&lt;/a&gt; package. For more information, check out the create-react-app &lt;a href="https://create-react-app.dev/"&gt;docs&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx create-react-app steam-sales-pagination;
cd steam-sales-pagination;
npm i axios;
npm start;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First lets create a custom hooks file called &lt;strong&gt;useFetchGames.js&lt;/strong&gt; in a helpers directory to handle fetching our data from &lt;strong&gt;CheapShark&lt;/strong&gt;. This custom hook will need to take in to take in user entered search parameters and the page number of results, so we need to declare them as props. &lt;/p&gt;

&lt;p&gt;Let's also declare our base URL we will be working with to call the API as a constant variable. We will be using &lt;strong&gt;axios&lt;/strong&gt; to make our API calls and the &lt;strong&gt;useEffect&lt;/strong&gt; and &lt;strong&gt;useReducer&lt;/strong&gt; hooks to handle user actions and fetching data, so let go ahead and import those as well.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// useFetchGames.js

...

import { useReducer, useEffect } from "react";
import axios from "axios";

const BASE_URL =
  "https://cors-anywhere.herokuapp.com/https://www.cheapshark.com/api/1.0/deals?storeID=1&amp;amp;pageSize=5";

export default function useFetchGames(params, page) {
  return &amp;lt;div&amp;gt;&amp;lt;/div&amp;gt;;
}

...

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Creating our Reducer
&lt;/h2&gt;

&lt;p&gt;Back in our &lt;strong&gt;useFetchGames&lt;/strong&gt; hook, lets create our reducer. First we will need to define our actions. Create an action for making the request, getting our data, error messages, and a next page.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// useFetchHooks.js

...

const ACTIONS = {
  MAKE_REQUEST: "make-request",
  GET_DATA: "get-data",
  ERROR: "error",
  NEXT_PAGE: "next-page",
};

...

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In our reducer, we will create a switch statement to handle our actions. In our &lt;strong&gt;MAKE_REQUEST&lt;/strong&gt; action we will set loading our loading variable to be true and our games array to be empty whenever a new request with new parameters is made. In our &lt;strong&gt;GET_DATA&lt;/strong&gt; action we will return the state, set the loading state back to false, and populate our games array from our action payload. In the case of our &lt;strong&gt;ERROR&lt;/strong&gt; action, we will do the same except the games array will be set to empty and our error variable will be set to our payload error. &lt;/p&gt;

&lt;p&gt;Our final action to set is &lt;strong&gt;NEXT_PAGE&lt;/strong&gt;. We will be dispatching this action after checking for another page of results with our second API call. We will define the payload below when we write our API calls.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// useFetchHooks.js

...

function reducer(state, action) {
  switch (action.type) {
    case ACTIONS.MAKE_REQUEST:
      return { loading: true, games: [] };
    case ACTIONS.GET_DATA:
      return { ...state, loading: false, games: action.payload.games };
    case ACTIONS.ERROR:
      return {
        ...state,
        loading: false,
        error: action.payload.error,
        games: [],
      };
    case ACTIONS.NEXT_PAGE:
      return { ...state, hasNextPage: action.payload.hasNextPage };
    default:
      return state;
  }
}

...

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that our actions are defined, let us finish writing our hook. First we need to pass the &lt;strong&gt;useReducer&lt;/strong&gt; hook from react to our reducer and our initial state. &lt;strong&gt;useReducer&lt;/strong&gt; will return us our state and dispatch function. We can set our hook to return our state now.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// useFetchHooks.js

...

export default function useFetchGames(params, page) {
  const [state, dispatch] = useReducer(reducer, { games: [], loading: true });
  return state;
}

...

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We will be using the &lt;strong&gt;useEffect&lt;/strong&gt; hook from react to dispatch our actions each time our parameters change. Since we will be calling &lt;strong&gt;useEffect&lt;/strong&gt; each time our parameters change, we will need to cancel our request process if the user is entering more parameters as our requests are made. We will set up a cancel token from axios and set &lt;strong&gt;useEffect&lt;/strong&gt; to return when that happens. You can read more about cancel tokens from axios &lt;a href="https://github.com/axios/axios#cancellation"&gt;here&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;After getting our first batch of data, we will need to make another request with the same parameters with the page number incremented one higher. Whether if there is data returned on a next page, it is here we will dispatch our &lt;strong&gt;NEXT_PAGE&lt;/strong&gt; action to be true or false. Here is how your hook should look:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// useFetchHooks.js

...

export default function useFetchGames(params, page) {
  const [state, dispatch] = useReducer(reducer, { games: [], loading: true });

  useEffect(() =&amp;gt; {
    const cancelToken1 = axios.CancelToken.source();
    dispatch({ type: ACTIONS.MAKE_REQUEST });
    axios
      .get(BASE_URL, {
        cancelToken: cancelToken1.token,
        params: { pageNumber: page, ...params },
      })
      .then((res) =&amp;gt; {
        dispatch({ type: ACTIONS.GET_DATA, payload: { games: res.data } });
      })
      .catch((e) =&amp;gt; {
        if (axios.isCancel(e)) return;
        dispatch({ type: ACTIONS.ERROR, payload: { error: e } });
      });

    const cancelToken2 = axios.CancelToken.source();
    axios
      .get(BASE_URL, {
        cancelToken: cancelToken2.token,
        params: { pageNumber: page + 1, ...params },
      })
      .then((res) =&amp;gt; {
        dispatch({
          type: ACTIONS.NEXT_PAGE,
          payload: { hasNextPage: res.data.length !== 0 },
        });
      })
      .catch((e) =&amp;gt; {
        if (axios.isCancel(e)) return;
        dispatch({ type: ACTIONS.ERROR, payload: { error: e } });
      });

    return () =&amp;gt; {
      cancelToken1.cancel();
      cancelToken2.cancel();
    };
  }, [params, page]);

  return state;
}

...

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Testing our Fetch Hook
&lt;/h2&gt;

&lt;p&gt;Let's head back to our main App.js import &lt;strong&gt;useFetchGames&lt;/strong&gt;. We will need to import the &lt;strong&gt;useState&lt;/strong&gt; hook. Set the initial state for our parameters to an empty object and our default page to be 0. &lt;/p&gt;

&lt;p&gt;After that, we can pass our parameters and page number to our &lt;strong&gt;useFetchGames&lt;/strong&gt; hook. &lt;strong&gt;useFetchGames&lt;/strong&gt; will be returning our array of games, loading state, potential error messages, and whether another page of data can be fetched from the API. We can log our results as a test. If you run the app now, you can see the default results populated in our console.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// App.js

...

import { useState } from "react";
import useFetchGames from "./helpers/useFetchGames";

function App() {
  const [params, setParams] = useState({});
  const [page, setPage] = useState(0);
  const { games, loading, error, hasNextPage } = useFetchGames(params, page);

  console.log(games, loading, error, hasNextPage);

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;h1&amp;gt;Seach Steam Sales&amp;lt;/h1&amp;gt;
      &amp;lt;h5&amp;gt;
        Powered by &amp;lt;a href="https://apidocs.cheapshark.com/"&amp;gt;CheapShark API&amp;lt;/a&amp;gt;
      &amp;lt;/h5&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}

export default App;

...

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Setting Up Our Search Form
&lt;/h2&gt;

&lt;p&gt;Right now, we nor the user cannot change the parameters to fetch more specific data, so let us build out our UI. First, install the react-bootstrap package so that we can easily template out some user components.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
npm i react-bootstrap

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, let us create a new functional component called SearchForm.js under a new Components directory in our project. Here is an example of some of the parameter searches formatted with react-boostrap elements. &lt;/p&gt;

&lt;p&gt;Make sure you give the name element in each search component matching the parameter name found on &lt;a href="https://apidocs.cheapshark.com/"&gt;CheapShark API&lt;/a&gt;. I have used title, upperPrice, and lowerPrice as an example.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// SearchForm.js

...

import React from "react";
import { Form, Col } from "react-bootstrap";

export default function SearchForm({ params, onParamChange }) {
  return (
    &amp;lt;Form className="mb-4"&amp;gt;
      &amp;lt;Form.Row className="align-items-end"&amp;gt;
        &amp;lt;Form.Group as={Col}&amp;gt;
          &amp;lt;Form.Label&amp;gt;Title&amp;lt;/Form.Label&amp;gt;
          &amp;lt;Form.Control
            placeholder="eg. Bioshock"
            onChange={onParamChange}
            value={params.title}
            name="title"
            type="text"
          /&amp;gt;
        &amp;lt;/Form.Group&amp;gt;
        &amp;lt;Form.Group as={Col}&amp;gt;
          &amp;lt;Form.Label&amp;gt;Highest Price&amp;lt;/Form.Label&amp;gt;
          &amp;lt;Form.Control
            placeholder="eg. 29.99"
            onChange={onParamChange}
            value={params.upperPrice}
            name="upperPrice"
            type="text"
          /&amp;gt;
        &amp;lt;/Form.Group&amp;gt;
        &amp;lt;Form.Group as={Col}&amp;gt;
          &amp;lt;Form.Label&amp;gt;Lowest Price&amp;lt;/Form.Label&amp;gt;
          &amp;lt;Form.Control
            placeholder="eg. 5.99"
            onChange={onParamChange}
            value={params.lowerPrice}
            name="lowerPrice"
            type="text"
          /&amp;gt;
        &amp;lt;/Form.Group&amp;gt;
      &amp;lt;/Form.Row&amp;gt;
    &amp;lt;/Form&amp;gt;
  );
}


...

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's head back to our &lt;strong&gt;App.js&lt;/strong&gt; and create a handler function for our parameter changes. In &lt;strong&gt;SearchForm.js&lt;/strong&gt; we set the names of our parameters to match the parameters found in our API, so now we can set our parameters in an array. The beauty of this is that we can expand the app and add more search parameters in a modular format easily. All you would need to do is add another element to &lt;strong&gt;SearchForm.js&lt;/strong&gt; with a matching name parameter to our API. &lt;/p&gt;

&lt;p&gt;Also, we will set the page result to send to the API back to 0 when the search parameters change. Next pass both the parameter and handler function to our search form component. Now we will be able to test adding parameters to our search and see them logged in the console.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// App.js

...

  const handleParamChange = (e) =&amp;gt; {
    const param = e.target.name;
    const value = e.target.value;
    setPage(0);
    setParams((prevParams) =&amp;gt; {
      return { ...prevParams, [param]: value };
    });
  };

...

&amp;lt;SearchForm params={params} onParamChange={handleParamChange} /&amp;gt;

...

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Displaying Our Results
&lt;/h2&gt;

&lt;p&gt;Now that we can change our search parameters and effectively fetch data from our API, let us create some demo UI elements to display our findings. Create another functional component &lt;strong&gt;Game.js&lt;/strong&gt; that takes in the game objects from the API as a prop. Check out the &lt;strong&gt;CheapShark API&lt;/strong&gt; &lt;a href="(https://apidocs.cheapshark.com/)"&gt;docs&lt;/a&gt; to see what game metadata you have to work with. &lt;/p&gt;

&lt;p&gt;Here is an example displaying the game title, sale prices, release dates, and a link to the game on the Steam storefront:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Game.js

...

import React, { useState } from "react";
import { Card, Button, Collapse } from "react-bootstrap";

export default function Game({ game }) {
  const [open, setOpen] = useState(false);

  return (
    &amp;lt;Card className="mb-3"&amp;gt;
      &amp;lt;Card.Body&amp;gt;
        &amp;lt;div className="d-flex justify-content-between"&amp;gt;
          &amp;lt;div&amp;gt;
            &amp;lt;Card.Title&amp;gt;
              {game.title} -{" "}
              &amp;lt;span
                className="text-muted font-weight-light"
                style={{ textDecoration: "line-through" }}
              &amp;gt;
                ${game.normalPrice}
              &amp;lt;/span&amp;gt;
              &amp;lt;span&amp;gt;{" - "}&amp;lt;/span&amp;gt;
              &amp;lt;span className="font-weight-light"&amp;gt;${game.salePrice}&amp;lt;/span&amp;gt;
            &amp;lt;/Card.Title&amp;gt;
            &amp;lt;Card.Subtitle className="text-muted mb-2"&amp;gt;
              Release Date:{" "}
              {new Date(game.releaseDate * 1000).toLocaleDateString()}
            &amp;lt;/Card.Subtitle&amp;gt;
          &amp;lt;/div&amp;gt;
          &amp;lt;img
            className="d-none d-md-block"
            height="50"
            alt={game.title}
            src={game.thumb}
          /&amp;gt;
        &amp;lt;/div&amp;gt;
        &amp;lt;Card.Text&amp;gt;
          &amp;lt;Button
            onClick={() =&amp;gt; setOpen((prevOpen) =&amp;gt; !prevOpen)}
            variant="primary"
          &amp;gt;
            {open ? "Hide Details" : "View Details"}
          &amp;lt;/Button&amp;gt;
        &amp;lt;/Card.Text&amp;gt;
        &amp;lt;Collapse in={open}&amp;gt;
          &amp;lt;div className="mt-4"&amp;gt;
            &amp;lt;div&amp;gt;Metacritic Score: {game.metacriticScore}&amp;lt;/div&amp;gt;
            &amp;lt;Button
              variant="success"
              href={`https://store.steampowered.com/app/${game.steamAppID}/`}
            &amp;gt;
              Check it out
            &amp;lt;/Button&amp;gt;
          &amp;lt;/div&amp;gt;
        &amp;lt;/Collapse&amp;gt;
      &amp;lt;/Card.Body&amp;gt;
    &amp;lt;/Card&amp;gt;
  );
}

...

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we can import our Game component into our &lt;strong&gt;App.js&lt;/strong&gt;. We will import the Container and Spinner component from react-bootstrap so that we can contain our Game component and show a spinner while our app is fetching the data. We can also add in an if statement to display our errors from the API if they occur.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// App.js
...

import { Container, Spinner } from "react-bootstrap";
import Game from "./components/Game";

...

  {loading &amp;amp;&amp;amp; &amp;lt;Spinner animation="border" variant="primary" /&amp;gt;}
  {error &amp;amp;&amp;amp; &amp;lt;h1&amp;gt;{error.message}&amp;lt;/h1&amp;gt;}
  {games.map((game) =&amp;gt; {
    return &amp;lt;Game key={game.steamAppID} game={game} /&amp;gt;;
  })}

...

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Pagination
&lt;/h2&gt;

&lt;p&gt;Lastly, let us create pagination to let our user browse through multiple pages of search results. Create a &lt;strong&gt;Pagination.js&lt;/strong&gt; file under the Components directory. This functional component will take in page, setPage, and hasNextPage as props. &lt;/p&gt;

&lt;p&gt;Using the pagination component from react-bootstrap, we can create logic based on the page prop to only display the back button if the user has navigated past the first page and only display the next page button if the hasNextPage prop is true. Also, we can use logic based on the page prop to set the ellipsis component to display only if the user has navigated past the second page.&lt;/p&gt;

&lt;p&gt;We will a need a function to pass to our onClick elements to adjust the page prop up or down, based on which element the user wants to click to navigate. The function will take in the appropriate increment or decrement to use the setPage prop. When the setPage prop is called, our &lt;strong&gt;useEffect&lt;/strong&gt; hook in &lt;strong&gt;useFetchGame.js&lt;/strong&gt; will dispatch the action to make the next two API calls.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Pagination.js

import React from "react";
import { Pagination } from "react-bootstrap";

export default function GamesPagination({ page, setPage, hasNextPage }) {
  const adjustPage = (amount) =&amp;gt; {
    setPage((prevPage) =&amp;gt; prevPage + amount);
  };

  return (
    &amp;lt;Pagination&amp;gt;
      {page !== 0 &amp;amp;&amp;amp; &amp;lt;Pagination.Prev onClick={() =&amp;gt; adjustPage(-1)} /&amp;gt;}
      {page !== 0 &amp;amp;&amp;amp; (
        &amp;lt;Pagination.Item onClick={() =&amp;gt; setPage(0)}&amp;gt;1&amp;lt;/Pagination.Item&amp;gt;
      )}
      {page &amp;gt; 1 &amp;amp;&amp;amp; &amp;lt;Pagination.Ellipsis /&amp;gt;}
      {page &amp;gt; 1 &amp;amp;&amp;amp; (
        &amp;lt;Pagination.Item onClick={() =&amp;gt; adjustPage(-1)}&amp;gt;{page}&amp;lt;/Pagination.Item&amp;gt;
      )}
      &amp;lt;Pagination.Item active&amp;gt;{page + 1}&amp;lt;/Pagination.Item&amp;gt;
      {hasNextPage &amp;amp;&amp;amp; (
        &amp;lt;Pagination.Item onClick={() =&amp;gt; adjustPage(1)}&amp;gt;
          {page + 2}
        &amp;lt;/Pagination.Item&amp;gt;
      )}
      {hasNextPage &amp;amp;&amp;amp; &amp;lt;Pagination.Next onClick={() =&amp;gt; adjustPage(1)} /&amp;gt;}
    &amp;lt;/Pagination&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we can import and add our pagination component to our &lt;strong&gt;App.js&lt;/strong&gt; and pass it the page, setPage, and hasNextPage props. I have placed mine above and below our Game components so the user can navigate from the top or bottom.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// App.js

...

import Pagination from "./components/Pagination";

...

  &amp;lt;SearchForm params={params} onParamChange={handleParamChange} /&amp;gt;
  &amp;lt;Pagination page={page} setPage={setPage} hasNextPage={hasNextPage} /&amp;gt;
  {loading &amp;amp;&amp;amp; &amp;lt;Spinner animation="border" variant="primary" /&amp;gt;}
  {error &amp;amp;&amp;amp; &amp;lt;h1&amp;gt;{handleError(error)}&amp;lt;/h1&amp;gt;}
  {games.map((game) =&amp;gt; {
    return &amp;lt;Game key={game.steamAppID} game={game} /&amp;gt;;
  })}
  &amp;lt;Pagination page={page} setPage={setPage} hasNextPage={hasNextPage} /&amp;gt;

...

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Congratulations!!
&lt;/h2&gt;

&lt;p&gt;Now, you have a simple app to browse game sales on steam. If you want to take a look at the complete code, or create your own fork, check out my repo &lt;a href="https://github.com/joefstack/react-steam-sales"&gt;here&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>react</category>
      <category>webdev</category>
      <category>frontend</category>
      <category>javascript</category>
    </item>
    <item>
      <title>How to use Dynamic Imports in ES2020</title>
      <dc:creator>Joseph Chow</dc:creator>
      <pubDate>Tue, 29 Dec 2020 18:46:26 +0000</pubDate>
      <link>https://forem.com/chowjiaming/how-to-use-dynamic-imports-in-es2020-33dn</link>
      <guid>https://forem.com/chowjiaming/how-to-use-dynamic-imports-in-es2020-33dn</guid>
      <description>&lt;p&gt;One of the most exciting new features, for me, in &lt;a href="https://www.ecma-international.org/memento/tc39-m.htm"&gt;ES2020&lt;/a&gt; is the ability to dynamically import your files. This means that rather than importing all your potentially necessary files at the top of your file, you can just import files based on need.&lt;/p&gt;

&lt;h2&gt;
  
  
  Imports
&lt;/h2&gt;

&lt;p&gt;Import was introduced in &lt;strong&gt;ES2015&lt;/strong&gt;, since then we have been able to natively load our modules in our code. We could divide our modules into export classes or functions that organizes our code into manageable sections. However, the JavaScript engine needed to resolve all the imports first before executing the code. &lt;/p&gt;

&lt;h2&gt;
  
  
  Why use dynamic imports?
&lt;/h2&gt;

&lt;p&gt;As developers, we should always be aiming to reduce load times anywhere possible. It may not be necessary, but optimizing code always feels nice. Using dynamic imports, we can avoid importing a large bundle which will let us have blazing fast apps. Dynamic imports also allows us to navigate situations where a module you want to import does not exist when the component is first loaded. This way, you can set logic to load the files with only a few lines of code. &lt;/p&gt;

&lt;h2&gt;
  
  
  How do we use them?
&lt;/h2&gt;

&lt;p&gt;Here is an example with the old system introduced with &lt;strong&gt;ES2015&lt;/strong&gt;. Note that without extra bundling tools, we need to set the &lt;strong&gt;type&lt;/strong&gt; attribute specifically to &lt;strong&gt;module&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
&amp;lt;script type="module"&amp;gt;
  import add from './add.js';

  add(7, 4); // returns 11
&amp;lt;/script&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;ES2020&lt;/strong&gt; allows us to use the &lt;strong&gt;import&lt;/strong&gt; keyword as a function. There is now also no need to set the type because &lt;strong&gt;import()&lt;/strong&gt; will work from a script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
&amp;lt;!-- No need to typeset --&amp;gt;
&amp;lt;script&amp;gt;
  import('./add.js')
    .then(module =&amp;gt; module.default(3, 7)) //returns 10
    .catch(error =&amp;gt; // log error here);
&amp;lt;/script&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A really common use case scenario is when you may potentially never need to import a module, like when something is loaded dependent on user action. For example, this allows us to be super flexible loading page modules based on button presses:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
document.getElementById("button")
.addEventListener("click", async () =&amp;gt; {
    const { nextPage } = await import("./NextPage.js");
    nextPage();
});

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the user experience is improved with snappier loads with only a few simple refactors. If you want to read more about &lt;strong&gt;ES2020&lt;/strong&gt; and &lt;strong&gt;Dynamic Importing&lt;/strong&gt;, check out  the MDN &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import#Dynamic_Imports"&gt;docs&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Originally published at &lt;a href="https://www.josephc.how/dynamic-imports-es2020/"&gt;https://www.josephc.how/dynamic-imports-es2020/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>es2020</category>
    </item>
    <item>
      <title>How to do Dark Mode with React Hooks</title>
      <dc:creator>Joseph Chow</dc:creator>
      <pubDate>Tue, 29 Dec 2020 17:52:31 +0000</pubDate>
      <link>https://forem.com/chowjiaming/how-to-do-dark-mode-with-react-hooks-23gi</link>
      <guid>https://forem.com/chowjiaming/how-to-do-dark-mode-with-react-hooks-23gi</guid>
      <description>&lt;p&gt;&lt;strong&gt;Dark Mode&lt;/strong&gt; is one of the latest features being widely adopted across apps and websites. Dark colours can prolong the battery life of mobile devices. The savings, according to &lt;a href="https://www.youtube.com/watch?time_continue=64&amp;amp;v=N_6sPd0Jd3g"&gt;Google&lt;/a&gt; with the Dark Mode offered on the YouTube app, allows a 15 percent energy reduction at 50 percent brightness and a huge 60 percent reduction at 100 percent bightness. &lt;a href="https://9to5mac.com/2019/01/22/apple-oled-iphone-2020/"&gt;Apple&lt;/a&gt; confirmed moving forward in 2020, their phones will feature OLED screens. &lt;/p&gt;

&lt;p&gt;Check out the completed demo &lt;a href="https://react-hooks-dark-mode-example.netlify.app/"&gt;here&lt;/a&gt;. The completed code for this demo can be found &lt;a href="https://github.com/joefstack/react-hooks-dark-mode"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why React Hooks
&lt;/h2&gt;

&lt;p&gt;We know with React components allows top-down data flow that helps us organize an application into small manageable pieces of UI. However, with only the component model, components become large and difficult to refactor. In addition, logic may need to be duplicated between components. Hooks are great because they allow us to organize logic within a component into discreet units that are easy to reuse.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;However, we often can’t break complex components down any further because the logic is stateful and can’t be extracted to a function or another component. - &lt;a href="https://dev.to/dan_abramov/making-sense-of-react-hooks-2eib"&gt;Dan Abramov&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Implementing Hooks
&lt;/h2&gt;

&lt;p&gt;For simplicity in demonstrating how to implement &lt;strong&gt;React Hooks&lt;/strong&gt; with &lt;strong&gt;Dark Mode&lt;/strong&gt;,  we will be using &lt;strong&gt;localStorage&lt;/strong&gt; so the browser will remember our user's preference upon reload. In more complex web applications, the user's preference can be stored in a database. So let's begin with Facebook's standard React boilerplate. Clone the repo, change directory into the newly created project folder, and run the application. For more information, check out the &lt;a href="https://create-react-app.dev/"&gt;docs&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx create-react-app dark-mode;
cd dark-mode;
npm start;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, let's add our CSS colour variables. We can start with just a colour and a background colour, but you can add more if you would like to build out a larger colour scheme. This way, we are modularizing our colour styling in a consistent way that can be easily implemented across our site.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// App.css

...

html[data-theme="light"]  {
  --color: rgb(5, 5, 5);
  --background-color: rgb(250, 250, 250);
}

html[data-theme="dark"]  {
  --color: rgb(250, 250, 250);
  --background-color: rgb(5, 5, 5);
}

...

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To set the variables, replace the header &lt;strong&gt;CSS&lt;/strong&gt; in the &lt;strong&gt;App.css&lt;/strong&gt; file like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// App.css

...

.App-header {
  background-color:var(--background-color);
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  font-size: calc(10px + 2vmin);
  color:var(--color);
}

...

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Creating theme-toggle component
&lt;/h2&gt;

&lt;p&gt;Create a new file in the &lt;strong&gt;src* folder and name it **ThemeToggle&lt;/strong&gt;, or something to that effect. This is currently a starter project, if you like, you can create a separate &lt;strong&gt;ThemeToggle&lt;/strong&gt; directory. Here, we are going to 'use' the &lt;strong&gt;useState&lt;/strong&gt; hook to store the current theme preference.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// ThemeToggle.js

...

  const ThemeToggle = () =&amp;gt; {
    const [darkMode, setDarkMode] = useState(
      localStorage.getItem("theme") === "dark" ? true : false
    );
    useEffect(() =&amp;gt; {
      document
        .getElementsByTagName("HTML")[0]
        .setAttribute("data-theme", localStorage.getItem("theme"));
    }, []);
  };

...

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If a user is accessing the site for the first time, there will not be a preference set in the &lt;strong&gt;localStorage&lt;/strong&gt;. Our &lt;strong&gt;Strict Equality Comparison&lt;/strong&gt; operator will throw &lt;strong&gt;false&lt;/strong&gt; and the &lt;strong&gt;darkMode&lt;/strong&gt; hook to apply the light theme across the application.&lt;/p&gt;

&lt;p&gt;This is done using the HTML &lt;strong&gt;data-&lt;/strong&gt; &lt;a href="https://developer.mozilla.org/en-US/docs/Learn/HTML/Howto/Use_data_attributes"&gt;attribute&lt;/a&gt;, which allows us to store information in semantic HTML elements. We will use it in the method that is going to be triggered to switch the theme to dark, or vice-versa. Using the same logic, we can also call our &lt;strong&gt;setDarkMode&lt;/strong&gt; hook from earlier to set the theme in &lt;strong&gt;localStorage&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// ThemeToggle.js

...

  const switchThemes = () =&amp;gt; {
    if (isDark === false) {
      localStorage.setItem("theme", "dark");
      document
        .getElementsByTagName("HTML")[0]
        .setAttribute("data-theme", localStorage.getItem("theme"));
      setDarkMode(true);
    } else {
      localStorage.setItem("theme", "light");
      document
        .getElementsByTagName("HTML")[0]
        .setAttribute("data-theme", localStorage.getItem("theme"));
      setDarkMode(false);
    }
  };

...

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The last thing we need to do in &lt;strong&gt;ThemeToggle&lt;/strong&gt; is return the button to be imported.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// ThemeToggle.js

...

  return (
    &amp;lt;label className="switch"&amp;gt;
      &amp;lt;input
        type="checkbox"
        defaultChecked={isDark}
        onChange={() =&amp;gt; toggleThemeChange()}
      /&amp;gt;
      &amp;lt;span className="slider round" /&amp;gt;
    &amp;lt;/label&amp;gt;
  );

...

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, to test, we can import it into our &lt;strong&gt;App.js&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// App.js

...

function App() {
  return (
    &amp;lt;div className="App"&amp;gt;
      &amp;lt;header className="App-header"&amp;gt;
        &amp;lt;img src={logo} className="App-logo" alt="logo" /&amp;gt;
        &amp;lt;p&amp;gt;
          React Hooks Dark Mode Starter
        &amp;lt;/p&amp;gt;
        &amp;lt;ThemeToggle /&amp;gt;
      &amp;lt;/header&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}

...

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Congratulations!!
&lt;/h2&gt;

&lt;p&gt;Now, you have a usable element that can place wherever you want in your application. If you want to take a look at the complete code, or create your own fork, check out my repo &lt;a href="https://github.com/joefstack/react-hooks-dark-mode"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Originally published at &lt;a href="https://www.josephc.how/react-hooks-dark-mode/"&gt;https://www.josephc.how/react-hooks-dark-mode/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>webdev</category>
      <category>javascript</category>
      <category>css</category>
    </item>
  </channel>
</rss>
