Full Blog TOC

Full Blog Table Of Content with Keywords Available HERE

Thursday, July 24, 2025

React Application Using Vite

 




In recent years it seems that Vite is replacing the old known create-react-app. I've gave it a try, and it is working great. By comparison to create-react-app, it is faster and has a better flexible configuration preventing the need the eject. Listed below are the basic steps to create a react-redux application including CSS modules and async thunk requests.


Installation


To start we need to have a recent NPM & Node installed, so we better update it using NVM:


nvm install --lts


Next we run the command to create our new project:


npm create vite@latest


And we follow the instructions until the project is created, and we can run it:

cd my-vite
npm install
npm run dev


We add the redux support:

npm install -S @reduxjs/toolkit react-redux


And we can start the development.


Framework Code


We create the redux main store (it includes import to the component that we will add later).


store.jsx

import {configureStore} from '@reduxjs/toolkit'

import box from "./component/box/slice.jsx"

export const store = configureStore({
middleware: (getDefaultMiddleware) => getDefaultMiddleware({
immutableCheck: {ignoredPaths: ['graph']},
serializableCheck: {ignoredPaths: ['graph']},
}),
reducer: {
box,
},
})

export default store


We import this store in our main code.


main.jsx

import {StrictMode} from 'react'
import {createRoot} from 'react-dom/client'
import './index.css'
import App from './App.jsx'
import {Provider} from 'react-redux'
import store from './store'

createRoot(document.getElementById('root')).render(
<StrictMode>
<Provider store={store}>
<App/>
</Provider>
</StrictMode>,
)


We update the application to include our new component (again we will descibe it later).


App.jsx

import {useState} from 'react'
import './App.css'
import Box from "./component/box/component.jsx";

function App() {
const [count, setCount] = useState(0)

return (
<>
<div className="card">
<button onClick={() => setCount((count) => count + 1)}>
count is {count}
</button>
</div>
<Box
name="my-box"
/>
</>
)
}

export default App


The last thing to do it to add wrapper for calling to APIs.


request.jsx


export async function sendRequest(url, body) {
let fetchOptions = {
method: 'post',
headers: {
'Content-type': 'application/json',
},
body: JSON.stringify(body),
}

const response = await fetch(url, fetchOptions)

if (response.status === 200) {
const json = await response.json()
return {
ok: true,
response: json,
}
}

let error = await response.text()
try {
const parsed = JSON.parse(error)
if (parsed.message) {
error = parsed.message
}
} catch (e) {
// ignore - send the actual error text
}

return {
ok: false,
response: error,
}
}


Application Code


The last thing to do it to add our box component which like most components includes 3 files: the component GUI, the redux slice, and the CSS module.


component.jsx

import React from 'react'
import {useDispatch, useSelector} from 'react-redux'
import {selectState, updateBox, updateMyData} from './slice'
import styles from './component.module.css'


function Box(props) {
const {name} = props
const dispatch = useDispatch()
const state = useSelector(selectState)
const {boxWidth} = state

function clickHandler() {
dispatch(updateBox({doubleClick: false}))
}

function doubleClickHandler() {
dispatch(updateMyData())
dispatch(updateBox({doubleClick: true}))
}

const dynamicStyle = {
width: `${boxWidth}px`,
}

return (
<div
className={styles.boxStyle}
onClick={clickHandler}
onDoubleClick={doubleClickHandler}
style={dynamicStyle}
>
{name}
</div>
)
}

export default Box


component.module.css


.boxStyle{
background: blue;
color: yellow;
font-size: large;
font-weight: bold;
}


slice.jsx

import {createAsyncThunk, createSlice} from '@reduxjs/toolkit'
import {sendRequest} from "../request/request.jsx";


const initialState = {
boxWidth: 100,
}


export const updateMyData = createAsyncThunk(
'box/updateMyData',
async (input, thunkApi) => {
const state = thunkApi.getState()
const {box} = state
const {boxWidth} = box
const body = {
WIDTH: boxWidth,
}
const {response, ok} = await sendRequest('http://localhost:3000/my-api', body)

if (!ok) {
console.error(response)
return
}

console.log(response)
},
)

export const slice = createSlice({
name: 'box',
initialState,
reducers: {
updateBox: (state, action) => {
const {doubleClick} = action.payload
if (doubleClick) {
state.boxWidth = 100
} else {
state.boxWidth += 100
}
},
},
})

export const {updateBox} = slice.actions

export const selectState = (state) => state.box


export default slice.reducer


Final Note


I recommend using Vite since it is much faster and the result transpiled code works faster. It is alos a living project unlike the create-react-app which seems near death.


No comments:

Post a Comment