Skip to content

Useful snippets

Published: at 04:18 PM

Useful boilerplate snippets which help me.

Table of contents

Open Table of contents

React-Query

Popular server-side caching library for React that provides useful hooks to manage data fetching, caching, synchronization, and state management.

Setting up

npm install @tanstack/react-query
// queryClient.ts
import { QueryClient } from '@tanstack/react-query';

const queryClient = new QueryClient();

export default queryClient;

Wrap your App.ts / Main.ts with the QueryClientProvider

// App.ts
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import { QueryClientProvider } from '@tanstack/react-query';
import queryClient from './queryClient';

const root = ReactDOM.createRoot(document.getElementById('root'));

root.render(
  <QueryClientProvider client={queryClient}>
    <App />
  </QueryClientProvider>
);

Fetching data

I create my fetch requests in seperate files depending on the data such as fetchProducts.ts which contains all the fetch requests related to products, I then import them into the useQuery hook. For this example I will use the FakeStoreAPI and use products and id as the keys.

// fetchProducts.ts
export const getProducts = async () => {
  const res = await fetch(`https://fakestoreapi.com/products`);
  return res.json();
};

Then I create my useQuery hooks in a seperate file such as customHooks.ts.

// customHooks.ts
import { getProduct } from "./imports";

export const useGetProduct = (id: number) => {
  const { data: product, isLoading } = useQuery({
    queryKey: ["product", id],
    queryFn: () => getProduct(id),
  });
  return { product, isLoading };
};

Now I can then import the query into any of my components. In this instance I am using the FakeStoreAPI and getting the first product using the initial ID value as 1, everytime I click the button it will increase the ID by 1 until it gets to 20 which then resets to 1.

// Product.ts
import { useState } from "react";
import { useGetProduct } from "./customHooks";

const Product = () => {
  const [id, setId] = useState<number>(1);
  const { product, isLoading } = useGetProduct(id);

  const { title } = product ?? {};

  const changeId = () => {
    if (id === 20) {
      setId(1);
    } else {
      setId((prev) => prev + 1);
    }
  };

  return (
    <main>
      <h3>Products</h3>
      {isLoading ? (
        <p>LOADING...</p>
      ) : (
        <div>
          <h4>{title}</h4>
        </div>
      )}
      <button onClick={changeId}>Change ID</button>
      <p>Current ID: {id}</p>
    </main>
  );
};

export default Product;

This video is a good way to visual one of the main benefits of React-Query. As each time the button is pressed it will cache the data using the product and id key, if we encounter a new product you can see a flicker of a loading state. But once we have seen every product we can see from the second loop that each product is cached as no loading states appear.

Zustand

My preferred state management which I use in medium - large projects.

Setting up

npm install zustand
// useStorePrice

import { create } from "zustand";

interface StringStore {
  price: number;
  setPrice: (prc: number) => void;
}

const usePriceStore = create<StringStore>((set) => ({
  price: 0
  setPrice: (prc) => set({ price: prc }),
}));

export default useStringStore;

Then we can import it into any component.

// Price.tsx
import React from 'react'
import usePriceStore from './usePriceStore.ts'

export default function Price() {
  const { price, setPrice} = usePriceStore()
  return (
    <div>{price}</div>
  )
}

Conclusion


Next Post
Comparing backend technologies