Elevate Your Skills: Empower Your React App with React-Router-Dom State Lifting!

Elevate Your Skills: Empower Your React App with React-Router-Dom State Lifting!

ยท

4 min read

Understanding React states: A state is an object that represents the current state of a component. It holds data that can change over time, and it determines the behavior and rendering of the component. When a state is updated, React automatically re-renders the component to reflect the changes.
Here's a code snippet to illustrate this:

import { useState } from "react"

export function App () {
    const [count, setCount] = useState(0);
    const handleAdd = () => setCount(prev => prev + 1)
    return (
        <div>Count is { count } </div>
        <button onClick={handleAdd}>Increment</button>
    );
}

I have defined a basic count function with a button that increments the count state by one(1) each time it is clicked using the current state version and the updated version.
It is assumed that you now understand how React states work as we would delve deeper to see how we can move states to the URL.

Why Move states to URL?

For instance, we intend to build an e-commerce website using react js. We then intend to store all information about our website in the state :(
This isn't ideal as a product URL isn't supposed to be stored in a state. But Why?
Remember, the state lives in the user's device and is not accessible elsewhere. This will reduce our monetization rate as users can't share products with friends since it's all hard-coded in the state.
This becomes a good time to move states to the URL so that it is accessible by anyone and can be shared. ๐Ÿ˜Š

This is to say:

  • URL parameters can be bookmarked and shared

  • It improves User Experience by allowing users to navigate back and forth in a very convenient way.

Now, I can achieve this using React-Router. As this write-up isn't about React-Router, so I won't spend much time talking about it. You can check the documentation to learn more.
As usual, every library exports custom hooks to help carry out certain tasks in our application. react-router exported a custom useSearchParam hook.
))
The useSearchParam Hook: The useSearchParam hook is a simple way to read and update URL search parameters in a React component, making it easy to create bookmarkable and shareable links. It creates an instance o the browser's native URL so, it has so many methods that can fit in the requirement of your application.
This works with query parameters, it is denoted with the ? symbol.
Here's an example of how it is seen: https://shopify/sneakers?size=34 . The URL simply describes the path to a sneakers page with size=34 on Shopify.

Setting up our Application:

Assume you have a template with a list of all products, Let's delve into implementing Products with Sort functionality built-in state vs URL.

How we can achieve this by storing in the state:

  • create a component that accepts all global products as a prop to display the list of found products

  • create an object to store the filtered products

  • Carry out some product filtering by name.

  • render the filtered product to the user

import { useState } from "react"

export const productLists = (products) => {
    const [foundProduct, setFoundProduct] = useState([]);
    const [inputValue, setInputValue] = useState(null)

    const findByName = () => { 
        const filteredProducts = products ? products
       .filter(product => product.name.includes(inputValue.toLowerCase()))
             : null

        setFoundProduct(filteredProducts)
    }

    const AvailableProducts = foundProducts.map(newProduct=> (
        <div key={newProduct.id}>
            <h2>{ newProduct.name} </h2>
            <span>{newProduct.price}</span>
            <article>{newProduct.description}</article>
        </div>
   ))

    return (
        <>
           <div>
                <p>Search for a product </p>
                <input
                     val={inputValue}
                     onChange={e => setInputValue(e.target.value)}
                 />
                <button role="search" onClick={findByName}>Search</button>
           </div>


        <h1>Available product from your input</h1>
         <section>{AvailabeProducts}</section>
        </>
    );

}

Now, we understand this isn't efficient as the user might wish to share that sorted product with their friends. This becomes impossible as states live in a browser only.
Let's refactor this using the useSearchParam hook from react-router-dom to improve the user experience a bit.

  • import and use the useSearchParam hook from react-router-dom

  • store the current browser URL in a variable

  • and use the get method to get the variable of the products name (Maybe price or something)

  • filter based on the value of the variable. Here, I've used the name to filter

  • loop through the filtered array and return the appropriate Markup.

import { useState, useRef } from "react"
import { useSearchParam } from "react-router-dom"

export const productLists = (products) => {
   const [inputValue, setInputValue] = useState();
  const [searchParam, setSearchParam] = useSearchParam();
  const nameFilter = searchParam.get('name') 

   const filteredProducts = products ? products
      .filter(product => product.name === nameFilter))
            : null

    const AvailableProducts = filteredProducts.map(newProduct=> (
        <div key={newProduct.id}>
            <h2>{ newProduct.name} </h2>
            <span>{newProduct.price}</span>
            <article>{newProduct.description}</article>
        </div>
   ))

    return (
        <>
           <div>
                <p>Search for a product </p>
                <input
                     val={inputValue}
                     onChange={e => setInputValue(e.target.value)}
                 />
                <button role="search" 
                    onClick={() => setSearchParam({name: inputValue)}
                >Search</button>
           </div>


        <h1>Available product from your input</h1>
         <section>{AvailabeProducts}</section>
        </>
    );

}

And, that's how to lift state to URL at the basic level. You can refer to the react-router docs.

If you found this helpful, please consider following me on Twitter, giving it a like, leaving a comment, or supporting me by buying me a coffee through this link.

Did you find this article valuable?

Support Emmanuel odii by becoming a sponsor. Any amount is appreciated!

ย