« React + Vite + TS » : différence entre les versions

De Banane Atomic
Aller à la navigationAller à la recherche
Aucun résumé des modifications
 
(52 versions intermédiaires par le même utilisateur non affichées)
Ligne 1 : Ligne 1 :
[[Category:React]]
= Links =
= Links =
* [https://react.dev React]
* [https://react.dev React]
* [https://vite.dev Vite]
* [https://learn.microsoft.com/en-us/windows/dev-environment/javascript/react-overview Microsoft doc]
* [https://react.dev/learn/react-developer-tools React Developer Tools]
* [[Javascript#LINQ_équivalent|LINQ equivalent]]


= Exemple =
= Description =
React is a library. It lets you put components together, but it doesn’t prescribe how to do routing and data fetching.<br>
To build an entire app with React, we recommend a full-stack React framework like Next.js or Remix.
 
= Command line =
<kode lang='bash'>
# create a new project (framework: React, variant: TypeScript)
npm create vite@latest
 
# install the packages
npm install
 
# run the project
npm run dev
</kode>
 
= Basic App =
<filebox fn='public/index.html'>
<filebox fn='public/index.html'>
<body>
<body>
     <!-- hosts the React application -->
     <!-- hosts the React application -->
     <div id="app"></div>
     <div id="root"></div>
    <!-- import index.js generated from index.jsx by a bundler such as Snowpack -->
     <script type="module" src="/src/main.tsx"></script>
     <script type="module" src="/dist/index.js"></script>
</body>
</body>
</filebox>
</filebox>


<filebox fn='src/index.jsx'>
<filebox fn='src/main.tsx'>
import React from 'react';
import { StrictMode } from 'react'
import ReactDOM from 'react-dom';
import { createRoot } from 'react-dom/client'
import { CssBaseline } from '@mui/material';
 
import './index.css'
 
createRoot(document.getElementById('root')!).render(
  <StrictMode>
    <CssBaseline />
    <h1>My App</h1>
  </StrictMode>,
)
</filebox>
 
<filebox fn='src/index.css'>
body {
  display: flex;
  min-height: 100vh;
}


ReactDOM.render(
#root {
    <h1>Hello, world!</h1>,
  margin: 0 auto;
    document.getElementById('app')
  padding: 2rem;
);
  text-align: center;
}
</filebox>
</filebox>


<filebox fn='package.json'>
<filebox fn='package.json' collapsed>
{
{
    "scripts": {
  "name": "vite-project",
      "start": "snowpack dev",
  "private": true,
      "build": "snowpack build"
  "version": "0.0.0",
     },
  "type": "module",
    "dependencies": {
  "scripts": {
      "react": "^17.0.2",
    "dev": "vite",
      "react-dom": "^17.0.2"
    "build": "tsc -b && vite build",
    },
     "lint": "eslint .",
    "devDependencies": {
    "preview": "vite preview"
      "snowpack": "^3.8.8"
  },
     }
  "dependencies": {
    "react": "^18.3.1",
    "react-dom": "^18.3.1"
  },
  "devDependencies": {
    "@eslint/js": "^9.13.0",
    "@types/react": "^18.3.11",
    "@types/react-dom": "^18.3.1",
    "@vitejs/plugin-react": "^4.3.3",
    "eslint": "^9.13.0",
    "eslint-plugin-react-hooks": "^5.0.0",
    "eslint-plugin-react-refresh": "^0.4.13",
    "globals": "^15.11.0",
    "typescript": "~5.6.2",
    "typescript-eslint": "^8.10.0",
     "vite": "^5.4.9"
   }
   }
}
</filebox>
= Component =
<filebox fn='src/App.tsx'>
import { useState } from 'react'
import './App.css'
export default function App() {
  const [count, setCount] = useState(0)
  return (
    <>
      <h1>My App</h1>
    </>
  )
}
</filebox>
<kode lang='tsx'>
import App from './App.tsx'
<App />
</kode>
= Styling =
<filebox fn='App.tsx'>
import './App.css';
<div
  id='d1'
  className="container"
  style={{ display: flex }}
></div>
</filebox>
<filebox fn='App.css'>
#d1 { }
.container { }
</filebox>
== CSS module ==
<filebox fn='App.tsx'>
import styles from './App.css';
<div className={styles.container}></div>
</filebox>
<filebox fn='App.module.css'>
.container { }
</filebox>
= [https://mui.com/material-ui/customization/palette Palette and Color] =
{| class="wikitable wtp"
|+ Default colors
! Value
! Color
|-
| primary || blue
|-
| secondary || violet
|-
| error || red
|-
| warning || orange
|-
| info || blue
|-
| success || green
|}
= [https://react.dev/reference/react/hooks Hooks] =
== [https://react.dev/reference/react/hooks#state-hooks State] ==
Allows to store values.
<kode lang='tsx'>
// items is the variable used to store the items
// setItems is a function to set a new value to items
const [items, setItems] = useState<Item[]>([]);
</kode>
== [https://react.dev/reference/react/hooks#effect-hooks Effect] ==
Allows to connect a component to an external system.
<kode lang='tsx'>
useEffect(() => {
  const fetchData = async () => {
    const result = await axios(`${API}?query=react`);
  };
    
    
  fetchData();
}, []);
</kode>
= [https://react.dev/learn/responding-to-events Responding to Events] =
<kode lang='tsx'>
export default function Button() {
  function handleClick() {
    alert('You clicked me!');
  }
  return (
    <button onClick={handleClick}>
      Click me
    </button>
  );
}
</kode>
= Form =
<filebox fn='EditItemForm.tsx' collapsed>
import { useState } from 'react';
import { TextField, Button, Box, Typography } from '@mui/material';
import { useParams, useNavigate } from 'react-router-dom';
import SaveIcon from '@mui/icons-material/Save';
import CancelIcon from '@mui/icons-material/Cancel';
export default function EditItemForm() {
    const { id } = useParams<{ id: string }>();
    const navigate = useNavigate();
    const initialData = {
        name: id === "1" ? 'Item 1' : 'Item X',
    };
    const [name, setName] = useState<string>(initialData.name);
    const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
        e.preventDefault(); // Prevent the default form submission
        console.log('Updated Data:', { name });
        navigate('/');
    };
    const handleCancel = () => {
        navigate('/'); // Navigate back to the item list without saving changes
    };
    return (
        <Box component="form" onSubmit={handleSubmit} sx={{ mt: 3 }}>
            <Typography variant="h4" gutterBottom>
                Edit Item
            </Typography>
            <TextField
                label="Name"
                variant="outlined"
                fullWidth
                margin="normal"
                value={name}
                onChange={(e) => setName(e.target.value)}
                required
            />
            <Box>
                <Button variant="contained" color="primary" type="submit" startIcon={<SaveIcon />} sx={{ mr: 1 }}>
                    Save
                </Button>
                <Button variant="outlined" color="secondary" onClick={handleCancel} startIcon={<CancelIcon />}>
                    Cancel
                </Button>
            </Box>
        </Box>
    )
}
</filebox>
</filebox>


<kode lang='bash'>
= Visual Studio Code =
# install the NodeJS packages
== Debug ==
npm i
Install the {{boxx|Debugger for Firefox}} extension.
<filebox fn='.vscode/launch.json'>
{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Launch Firefox against localhost",
            "type": "firefox",
            "request": "launch",
            "url": "http://localhost:5173",
            "webRoot": "${workspaceFolder}"
        }
    ]
}
</filebox>


# run the app
= [https://github.com/airbnb/javascript/tree/master/react#naming Naming convention] =
npm start
* file name: PascalCase
<kode lang='tsx'>
// use the filename as the component name, so PascalCase
import App from './App.tsx'
</kode>
</kode>


= [https://www.snowpack.dev SnowPack] =
= Component libraries =
* [[Material-UI|Material-UI components library]]
* [https://react-bootstrap.netlify.app React Boostrap]

Dernière version du 27 octobre 2024 à 21:42

Links

Description

React is a library. It lets you put components together, but it doesn’t prescribe how to do routing and data fetching.
To build an entire app with React, we recommend a full-stack React framework like Next.js or Remix.

Command line

Bash.svg
# create a new project (framework: React, variant: TypeScript)
npm create vite@latest

# install the packages
npm install

# run the project
npm run dev

Basic App

public/index.html
<body>
    <!-- hosts the React application -->
    <div id="root"></div>
    <script type="module" src="/src/main.tsx"></script>
</body>
src/main.tsx
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import { CssBaseline } from '@mui/material';

import './index.css'

createRoot(document.getElementById('root')!).render(
  <StrictMode>
    <CssBaseline />
    <h1>My App</h1>
  </StrictMode>,
)
src/index.css
body {
  display: flex;
  min-height: 100vh;
}

#root {
  margin: 0 auto;
  padding: 2rem;
  text-align: center;
}
package.json
{
  "name": "vite-project",
  "private": true,
  "version": "0.0.0",
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "tsc -b && vite build",
    "lint": "eslint .",
    "preview": "vite preview"
  },
  "dependencies": {
    "react": "^18.3.1",
    "react-dom": "^18.3.1"
  },
  "devDependencies": {
    "@eslint/js": "^9.13.0",
    "@types/react": "^18.3.11",
    "@types/react-dom": "^18.3.1",
    "@vitejs/plugin-react": "^4.3.3",
    "eslint": "^9.13.0",
    "eslint-plugin-react-hooks": "^5.0.0",
    "eslint-plugin-react-refresh": "^0.4.13",
    "globals": "^15.11.0",
    "typescript": "~5.6.2",
    "typescript-eslint": "^8.10.0",
    "vite": "^5.4.9"
  }
}

Component

src/App.tsx
import { useState } from 'react'
import './App.css'

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

  return (
    <>
      <h1>My App</h1>
    </>
  )
}
Tsx.svg
import App from './App.tsx'

<App />

Styling

App.tsx
import './App.css';

<div
  id='d1'
  className="container"
  style={{ display: flex }}
></div>
App.css
#d1 { }
.container { }

CSS module

App.tsx
import styles from './App.css';

<div className={styles.container}></div>
App.module.css
.container { }

Palette and Color

Default colors
Value Color
primary blue
secondary violet
error red
warning orange
info blue
success green

Hooks

State

Allows to store values.

Tsx.svg
// items is the variable used to store the items
// setItems is a function to set a new value to items
const [items, setItems] = useState<Item[]>([]);

Effect

Allows to connect a component to an external system.

Tsx.svg
useEffect(() => {
  const fetchData = async () => {
    const result = await axios(`${API}?query=react`);
  };
  
  fetchData();
}, []);

Responding to Events

Tsx.svg
export default function Button() {
  function handleClick() {
    alert('You clicked me!');
  }

  return (
    <button onClick={handleClick}>
      Click me
    </button>
  );
}

Form

EditItemForm.tsx
import { useState } from 'react';
import { TextField, Button, Box, Typography } from '@mui/material';
import { useParams, useNavigate } from 'react-router-dom';

import SaveIcon from '@mui/icons-material/Save';
import CancelIcon from '@mui/icons-material/Cancel';

export default function EditItemForm() {
    const { id } = useParams<{ id: string }>();
    const navigate = useNavigate();

    const initialData = {
        name: id === "1" ? 'Item 1' : 'Item X',
    };

    const [name, setName] = useState<string>(initialData.name);

    const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
        e.preventDefault(); // Prevent the default form submission
        console.log('Updated Data:', { name });
        navigate('/');
    };

    const handleCancel = () => {
        navigate('/'); // Navigate back to the item list without saving changes
    };

    return (
        <Box component="form" onSubmit={handleSubmit} sx={{ mt: 3 }}>
            <Typography variant="h4" gutterBottom>
                Edit Item
            </Typography>
            <TextField
                label="Name"
                variant="outlined"
                fullWidth
                margin="normal"
                value={name}
                onChange={(e) => setName(e.target.value)}
                required
            />
            <Box>
                <Button variant="contained" color="primary" type="submit" startIcon={<SaveIcon />} sx={{ mr: 1 }}>
                    Save
                </Button>
                <Button variant="outlined" color="secondary" onClick={handleCancel} startIcon={<CancelIcon />}>
                    Cancel
                </Button>
            </Box>
        </Box>
    )
}

Visual Studio Code

Debug

Install the Debugger for Firefox extension.

.vscode/launch.json
{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Launch Firefox against localhost",
            "type": "firefox",
            "request": "launch",
            "url": "http://localhost:5173",
            "webRoot": "${workspaceFolder}"
        }
    ]
}

Naming convention

  • file name: PascalCase
Tsx.svg
// use the filename as the component name, so PascalCase
import App from './App.tsx'

Component libraries