See Project DEMO on ๐ThisURL๐
This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
Currently, two official plugins are available:
- @vitejs/plugin-react uses Babel for Fast Refresh
- @vitejs/plugin-react-swc uses SWC for Fast Refresh
import { createBrowserRouter } from 'react-router';
import { RouterProvider } from 'react-router/dom';
import Route1, { loader as Route1Loader } from './components/Route1';
import Route2, { action as Route2Action } from './components/Route2';
import Route3 from './components/Route3';
import Home from './components/Home';
import Error from './components/Error';
const router = createBrowserRouter([
{
element: <RootRoute />,
errorElement: <Error />,
children: [
{
path: '/',
element: <Home />,
},
{
path: '/route1',
element: <Route1 />,
loader: Route1Loader,
errorElement: <Error />,
},
{
path: '/route2/nested',
element: <Route2 />,
action: Route2Action,
},
{
path: '/route2/:id',
element: <Route3 />,
},
],
},
]);
export default function App() {
return <RouterProvider router={router} />;
}import { useLoaderData } from 'react-router';
import { getData } from 'api';
export default function Component() {
const data = useLoaderData();
return <div>{data.key}</div>;
}
export async function loader() {
const data = await getData();
return data;
}import { postData } from 'api';
import { Form, redirect, useActionData, useNavigation } from 'react-router';
export default function Component() {
const errors = useActionData();
const navigation = useNavigation();
const isSubmitting = navigation.state === 'submitting';
return (
<Form method="POST">
<input type="X" name="y" />
</Form>
);
}
export async function action({ request }) {
const formData = await request.formData();
const data = Object.fromEntries(formData);
const errors = {};
if (ERROR1_CONDITION) {
errors.ERROR1 = 'ERROR MESSAGE!';
return errors;
}
if (ERROR2_CONDITION) {
errors.ERROR2 = 'ERROR MESSAGE!';
return errors;
}
const res = await postData(data);
return redirect(`/route/${res.id}`);
}import { useEffect } from 'react';
import { useFetcher } from 'react-router';
export default function Component() {
const fetcher = useFetcher();
useEffect(
function () {
if (!fetcher.data && fetcher.state === 'idle') fetcher.load('/menu');
},
[fetcher]
);
// Now the menu Data is available in fetcher.data
}import { useFetcher } from 'react-router';
import { updateData } from 'api';
export default function Component() {
const fetcher = useFetcher();
return (
<fetcher.Form method="PATCH">
<button>Update Data</button>
</fetcher.Form>
);
}
export async function action({ request, params }) {
const updatedAttribute = { key: 'newValue' };
await updateData(params.paramId, updatedAttribute);
return null;
}1. Installation : See Tailwind Docs
npm install -D tailwindcss@3 postcss autoprefixer
npx tailwindcss init -p/** @type {import('tailwindcss').Config} */
const config = {
content: ['./index.html', './src/**/*.{js,ts,jsx,tsx}'],
theme: {
extend: {},
},
plugins: [],
};
export default config;@tailwind base;
@tailwind components;
@tailwind utilities;2. Setup Prettier for Tailwind : See Tailwind Docs
npm install -D prettier prettier-plugin-tailwindcssconst config = {
semi: true,
singleQuote: true,
trailingComma: 'es5',
printWidth: 100,
plugins: ['prettier-plugin-tailwindcss'],
};
export default config;import { createAsyncThunk, createSlice } from '@reduxjs/toolkit';
export const fetchAction = createAsyncThunk('feature/fetchAction', async function () {
// Asynchronous Codes (await codes)
return data;
});
const initialState = {
status: 'idle',
data: [],
error: '',
};
const featureSlice = createSlice({
name: 'feature',
initialState,
reducers: {
action1(state, action) {
// Updating States
},
},
extraReducers: (bulder) =>
builder
.addCase(fetchAction.pending, (state, action) => {
// Pending Status : Update States
state.status = 'loading';
})
.addCase(fetchAction.fulfilled, (state, action) => {
// Fulfilled Status : Update States
state.data = action.payload;
state.status = 'idle';
})
.addCase(fetchAction.rejected, (state, action) => {
// Error Status : Update States
state.error = action.error.message;
state.status = 'error';
}),
});
export const { action1 } = featureSlice.actions;
export default featureSlice.reducer;
// Selector functions
export const getData = (store) => store.feature.data;const featureSlice = createSlice({
name: 'feature',
initialState,
reducers: {
action1(state, action) {
// Updating States
},
action2(state, action) {
// Updating States with action 1
featureSlice.caseReducers.action1(state, action);
},
},
});