├── README.md
├── postcss.config.js
├── vite.config.js
├── tailwind.config.js
├── src
├── main.jsx
├── App.css
├── index.css
├── App.jsx
└── assets
│ └── react.svg
├── .gitignore
├── index.html
├── backend
└── server.js
├── .eslintrc.cjs
├── package.json
├── .github
└── workflows
│ └── static.yml
└── public
└── vite.svg
/README.md:
--------------------------------------------------------------------------------
1 | # Connecting-React-to-Express-Backend
2 |
--------------------------------------------------------------------------------
/postcss.config.js:
--------------------------------------------------------------------------------
1 | export default {
2 | plugins: {
3 | tailwindcss: {},
4 | autoprefixer: {},
5 | },
6 | }
7 |
--------------------------------------------------------------------------------
/vite.config.js:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'vite'
2 | import react from '@vitejs/plugin-react'
3 |
4 | // https://vitejs.dev/config/
5 | export default defineConfig({
6 | plugins: [react()],
7 | })
8 |
--------------------------------------------------------------------------------
/tailwind.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('tailwindcss').Config} */
2 | export default {
3 | content: [
4 | "./index.html",
5 | "./src/**/*.{js,ts,jsx,tsx}",
6 | ],
7 | theme: {
8 | extend: {},
9 | },
10 | plugins: [],
11 | }
12 |
13 |
--------------------------------------------------------------------------------
/src/main.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import ReactDOM from 'react-dom/client'
3 | import App from './App.jsx'
4 | import './index.css'
5 |
6 | ReactDOM.createRoot(document.getElementById('root')).render(
7 |
8 |
9 | ,
10 | )
11 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | pnpm-debug.log*
8 | lerna-debug.log*
9 |
10 | node_modules
11 | dist
12 | dist-ssr
13 | *.local
14 |
15 | # Editor directories and files
16 | .vscode/*
17 | !.vscode/extensions.json
18 | .idea
19 | .DS_Store
20 | *.suo
21 | *.ntvs*
22 | *.njsproj
23 | *.sln
24 | *.sw?
25 |
--------------------------------------------------------------------------------
/src/App.css:
--------------------------------------------------------------------------------
1 | #root {
2 | max-width: 1280px;
3 | margin: 0 auto;
4 | padding: 2rem;
5 | text-align: center;
6 | }
7 |
8 | /* // await delay(2);
9 |
10 |
11 | // if (data.username !== "zain") {
12 | // setError("form", {message:"Your crendentials are invalid"})
13 | // }if(data.username === "rahat"){
14 | // setError("blocked", {message:"sorry this user is blocked"})
15 | // */
16 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Connecting-React-to-Express-Backend
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/backend/server.js:
--------------------------------------------------------------------------------
1 | import express from "express";
2 | import bodyParser from "body-parser";
3 | import cors from "cors";
4 |
5 | const app = express();
6 | const port = 3000;
7 |
8 | app.use(bodyParser.json());
9 | app.use(cors());
10 |
11 | app.get('/', (req, res) => {
12 | res.send('Hello World!');
13 | });
14 |
15 | app.post('/', (req, res) => {
16 | console.log(req.body);
17 | res.json({ message: 'Hello World!', username: req.body.username });
18 | });
19 |
20 | app.listen(port, () => {
21 | console.log(`Example app listening on port ${port}`);
22 | });
23 |
--------------------------------------------------------------------------------
/src/index.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
4 | body{
5 | font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
6 | line-height: 1.5;
7 | font-weight: 400;
8 |
9 | color-scheme: light dark;
10 | color: rgba(255, 255, 255, 0.87);
11 | background-color: #242424;
12 |
13 | font-synthesis: none;
14 | text-rendering: optimizeLegibility;
15 | -webkit-font-smoothing: antialiased;
16 | -moz-osx-font-smoothing: grayscale;
17 | }
18 | .red{
19 | color: red;
20 | font-size: 12px;
21 | text-align: start;
22 | }
23 |
24 |
--------------------------------------------------------------------------------
/.eslintrc.cjs:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | env: { browser: true, es2020: true },
4 | extends: [
5 | 'eslint:recommended',
6 | 'plugin:react/recommended',
7 | 'plugin:react/jsx-runtime',
8 | 'plugin:react-hooks/recommended',
9 | ],
10 | ignorePatterns: ['dist', '.eslintrc.cjs'],
11 | parserOptions: { ecmaVersion: 'latest', sourceType: 'module' },
12 | settings: { react: { version: '18.2' } },
13 | plugins: ['react-refresh'],
14 | rules: {
15 | 'react/jsx-no-target-blank': 'off',
16 | 'react-refresh/only-export-components': [
17 | 'warn',
18 | { allowConstantExport: true },
19 | ],
20 | },
21 | }
22 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "connecting-react-to-express-backend",
3 | "private": true,
4 | "version": "0.0.0",
5 | "type": "module",
6 | "scripts": {
7 | "dev": "vite",
8 | "build": "vite build",
9 | "lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0",
10 | "preview": "vite preview"
11 | },
12 | "dependencies": {
13 | "body-parser": "^1.20.2",
14 | "cors": "^2.8.5",
15 | "express": "^4.19.2",
16 | "react": "^18.2.0",
17 | "react-dom": "^18.2.0",
18 | "react-hook-form": "^7.51.5"
19 | },
20 | "devDependencies": {
21 | "@types/react": "^18.2.66",
22 | "@types/react-dom": "^18.2.22",
23 | "@vitejs/plugin-react": "^4.2.1",
24 | "autoprefixer": "^10.4.19",
25 | "eslint": "^8.57.0",
26 | "eslint-plugin-react": "^7.34.1",
27 | "eslint-plugin-react-hooks": "^4.6.0",
28 | "eslint-plugin-react-refresh": "^0.4.6",
29 | "postcss": "^8.4.38",
30 | "tailwindcss": "^3.4.4",
31 | "vite": "^5.2.0"
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/.github/workflows/static.yml:
--------------------------------------------------------------------------------
1 | # Simple workflow for deploying static content to GitHub Pages
2 | name: Deploy static content to Pages
3 |
4 | on:
5 | # Runs on pushes targeting the default branch
6 | push:
7 | branches: ["main"]
8 |
9 | # Allows you to run this workflow manually from the Actions tab
10 | workflow_dispatch:
11 |
12 | # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
13 | permissions:
14 | contents: read
15 | pages: write
16 | id-token: write
17 |
18 | # Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
19 | # However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
20 | concurrency:
21 | group: "pages"
22 | cancel-in-progress: false
23 |
24 | jobs:
25 | # Single deploy job since we're just deploying
26 | deploy:
27 | environment:
28 | name: github-pages
29 | url: ${{ steps.deployment.outputs.page_url }}
30 | runs-on: ubuntu-latest
31 | steps:
32 | - name: Checkout
33 | uses: actions/checkout@v4
34 | - name: Setup Pages
35 | uses: actions/configure-pages@v5
36 | - name: Upload artifact
37 | uses: actions/upload-pages-artifact@v3
38 | with:
39 | # Upload entire repository
40 | path: '.'
41 | - name: Deploy to GitHub Pages
42 | id: deployment
43 | uses: actions/deploy-pages@v4
44 |
--------------------------------------------------------------------------------
/public/vite.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/App.jsx:
--------------------------------------------------------------------------------
1 | import { useState } from 'react';
2 | import { useForm } from 'react-hook-form';
3 | import './App.css';
4 |
5 | function App() {
6 | const [isDataSaved, setIsDataSaved] = useState(false);
7 | const {
8 | register,
9 | handleSubmit,
10 | setError,
11 | reset,
12 | formState: { errors, isSubmitting }
13 | } = useForm();
14 |
15 | const delay = (d) => {
16 | return new Promise((resolve) => {
17 | setTimeout(() => {
18 | resolve();
19 | }, d * 1000);
20 | });
21 | }
22 |
23 | const onSubmit = async (data) => {
24 | await delay(2);
25 |
26 | try {
27 | const response = await fetch('http://localhost:3000/', {
28 | method: 'POST',
29 | headers: {
30 | 'Content-Type': 'application/json',
31 | },
32 | body: JSON.stringify(data),
33 | });
34 |
35 | if (!response.ok) {
36 | throw new Error('Network response was not ok');
37 | }
38 |
39 | const result = await response.json();
40 | console.log(result);
41 |
42 | setIsDataSaved(true);
43 | reset();
44 |
45 | } catch (error) {
46 | console.error('Error:', error);
47 | }
48 | };
49 |
50 | return (
51 |
52 |
53 | {isSubmitting &&
loading...
}
54 | {isDataSaved &&
Your data is saved
}
55 |
96 |
97 |
98 | );
99 | }
100 |
101 | export default App;
102 |
--------------------------------------------------------------------------------
/src/assets/react.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------