« React + Vite + TS » : différence entre les versions
De Banane Atomic
Aller à la navigationAller à la recherche
Aucun résumé des modifications |
|||
(59 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]] | |||
= | = Description = | ||
<filebox fn='index.html'> | 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'> | |||
<body> | <body> | ||
<!-- hosts the React application --> | <!-- hosts the React application --> | ||
<div id=" | <div id="root"></div> | ||
<script type="module" src="/src/main.tsx"></script> | |||
<script type="module" src="/ | |||
</body> | </body> | ||
</filebox> | </filebox> | ||
<filebox fn='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>, | |||
) | |||
</filebox> | |||
<filebox fn='src/index.css'> | |||
body { | |||
display: flex; | |||
min-height: 100vh; | |||
} | |||
#root { | |||
margin: 0 auto; | |||
padding: 2rem; | |||
text-align: center; | |||
} | |||
</filebox> | |||
<filebox fn='package.json' collapsed> | |||
{ | |||
"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" | |||
} | |||
} | |||
</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> | |||
= Visual Studio Code = | |||
== Debug == | |||
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> | |||
= [https://github.com/airbnb/javascript/tree/master/react#naming Naming convention] = | |||
* file name: PascalCase | |||
<kode lang='tsx'> | |||
// use the filename as the component name, so PascalCase | |||
import App from './App.tsx' | |||
</kode> | |||
= 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
# 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> </> ) } |
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
Value | Color |
---|---|
primary | blue |
secondary | violet |
error | red |
warning | orange |
info | blue |
success | green |
Hooks
State
Allows to store values.
// 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.
useEffect(() => { const fetchData = async () => { const result = await axios(`${API}?query=react`); }; fetchData(); }, []); |
Responding to Events
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
// use the filename as the component name, so PascalCase import App from './App.tsx' |