Les erreurs courantes en JS
Le bestiaire : reconnaitre les monstres a vue.
3.1Cannot read properties of undefined
Le boss le plus frequent. Tu essaies d'acceder a une propriete d'une variable qui est undefined.
// Le bug
const user = undefined
console.log(user.name) // TypeError !
// Le fix 1 : optional chaining
console.log(user?.name) // undefined (pas d'erreur)
// Le fix 2 : verifier avant
if (user) {
console.log(user.name)
}
// Le fix 3 : valeur par defaut
const name = user?.name ?? "Inconnu"3.2.map is not a function
Tu utilises .map() sur quelque chose qui n'est pas un tableau. Souvent parce que le fetch n'a pas encore fini.
// Le bug : data est null avant le fetch
const [articles, setArticles] = useState(null)
// ...
return articles.map(a => <div>{a.title}</div>) // TypeError !
// Le fix 1 : initialiser avec un tableau vide
const [articles, setArticles] = useState<Article[]>([])
// Le fix 2 : guard clause
return articles?.map(a => <div key={a.id}>{a.title}</div>) ?? <p>Chargement...</p>3.3is not defined (ReferenceError)
// Le bug : faute de frappe
const userName = "Alice"
console.log(usrName) // ReferenceError: usrName is not defined
// Le bug : import oublie
export function MyComponent() {
return <Button>Cliquer</Button> // ReferenceError si Button n'est pas importe
}
// Le fix : verifier l'import et l'orthographe
import { Button } from "@/components/ui/button"
console.log(userName) // OK3.4Objects are not valid as a React child
Tu essaies d'afficher un objet directement dans le JSX au lieu d'une string ou d'un nombre.
// Le bug
const user = { name: "Alice", email: "alice@mail.com" }
return <p>{user}</p> // Error: Objects are not valid as a React child
// Le fix : afficher une propriete, pas l'objet entier
return <p>{user.name}</p>
// Ou pour debugger : JSON.stringify
return <pre>{JSON.stringify(user, null, 2)}</pre>3.5Each child should have a unique "key" prop
// Le warning
users.map(user => <UserCard user={user} />) // Warning: Each child...
// Le fix : ajouter une key unique
users.map(user => <UserCard key={user.id} user={user} />)
// JAMAIS : utiliser l'index comme key si la liste change
// users.map((user, i) => <UserCard key={i} user={user} />) // Mauvaise idee !3.6Too many re-renders
React detecte une boucle infinie de re-renders. En general, c'est un setState appele directement dans le corps du composant.
// Le bug : setState appele a chaque render
function Counter() {
const [count, setCount] = useState(0)
setCount(count + 1) // BOUM ! Boucle infinie
return <p>{count}</p>
}
// Le fix : mettre dans un useEffect ou un handler
function Counter() {
const [count, setCount] = useState(0)
return (
<button onClick={() => setCount(c => c + 1)}>
{count}
</button>
)
}3.7Async/await oublie
// Le bug : oubli du await
async function getUser() {
const response = fetch("/api/user") // Oubli du await !
const data = response.json() // TypeError: response.json is not a function
return data
}
// Le fix : await a chaque etape
async function getUser() {
const response = await fetch("/api/user")
const data = await response.json()
return data
}3.8Le recapitulatif du bestiaire
| Monstre | Cause | Antidote |
|---|---|---|
| Cannot read undefined | Variable pas encore chargee | Optional chaining (?.) |
| .map is not a function | Pas un tableau | Initialiser avec [] |
| is not defined | Faute de frappe / import | Verifier orthographe |
| Objects are not valid | Objet dans le JSX | Afficher une propriete |
| Missing key prop | key manquante dans .map | Ajouter key={id} |
| Too many re-renders | setState dans le render | Handler ou useEffect |
| Promise non resolue | await oublie | Ajouter await |