Skip to content

newmediapilot/react-19-bike-shop

Repository files navigation

React + Vite : Bicycle Shop

"Proof of craft" project for testing React 19 and various FE
concepts in a sterile context.

Table of Contents

Live Demo

https://newmediapilot.github.io/react-19-bike-shop

Local

npm run dev  
npm run db // Separate window

All package.json commands

yarn run <command>

Script Command Description
dev vite Local development
build vite build Production build
db npx json-server public/db.json Local mock database
lint eslint my-app Linter
preview vite preview Preview production build
deploy bash script/deploy-preview.sh Deploy to preview
gw node util/watch.js Watch git for changes
gp node util/push.js Flatten branch && push -f

Technical Features

Redux + Loader

Each loader definition is processed by loaderHandler.tsx
It manages how states are hydrated (fetch or cached)

This is the general flow of data in loaderHandler:

  1. IF redux defined return redux data
  2. IF redux undefined use fetch
  3. IF fetch 200 set local && dispatch redux
  4. IF fetch errors stub fixture && continue...
  5. IF local defined overwrite stub
  6. dispatchredux

If the last step fails we fallback to fixture.
This is just so that gh-pages can function.

Prefetch

Since we aren't using NextJS we have to write a pre-fetch solution
Prefetch is handled by pf.ts

  • pf uses its own syntax to distribute a pre-fetch strategy
  • pf.loader("@api/list") prepares and returns a loader to invoke later
  • pf.prefetch("@api/list") downloads the data
  • pf.loader("id@api/list") prepares a loader and prepares loaders for sub-items
  • The produced list would hydrate id@api/list recursively as @api/list/[id]
  • We can then pre-fetch specific members as pf.prefetch("@api/list/[0-9]")
  • pf.events("id@api/list") is an onMouseOver mixin running pf.prefetch
// Preloads list items `onMouseOver`
<>
  list.map((data, key)=> {
    <NavLink key={key} {...pf.events(`@api/list/${key}`)}>View Item</NavLink>
  }
</>

Environment variables

Vite uses VITE_{VARIABLE} to define its environment by default.
.env() consumes and scans the files on compile.

Stubbed with http://localhost:3000 for npm run db
This will become your API root

Deployment

npm run deploy

  1. Resets node modules via npm run reset
  2. Prompts to flatten the current branch to the newest tag
  3. Prompts to make a deployment
  4. Bumps version and amends commit with build message
  5. Adds git tag
  6. Pushes to gh-pages

Component strategy

Each type of component adheres to state management differently

Layouts

  • Defines a grid strategy for its members
  • DRY composition layer for Flex, Grid, etc.
  • No selectors, injections or emits

Components

  • Only hydrate via selector
  • Should be simple to move around the page
  • Must use useSelector, cannot use props
  • Must fill their container w&h-[100%]

Components/Core

  • Only hydrate via props
  • Can exist anywhere, lightweight API
  • Must fill their container w&h-[100%]
  • Doesn't need to be visual eg. Suspense

Powered by:


References:

Tool URL Description Notes
Jotai https://github.com/pmndrs/jotai A great alternative to Redux or Zustand. Powerful and clean implementation (pre-fetch capable)
Daisy UI https://daisyui.com/ A UI component library based on Tailwind Similar to Radix & Skeleton

AI was used to generate db.json