React Fundamentals
React builds user interfaces from components: functions that take props and return JSX describing the UI.
Your first component
function Greeting({ name }) {
return <h1>Hello, {name}!</h1>;
}
export default function App() {
return <Greeting name="PrepVerse" />;
}
JSX rules
- Return one root element (or a fragment
<>...</>). - Use
classNameinstead ofclass, and camelCase for attributes (onClick). - Put JavaScript expressions in curly braces:
{count + 1}.
State
State is data that changes over time and re-renders the component.
import { useState } from "react";
export default function Counter() {
const [count, setCount] = useState(0);
return (
<button onClick={() => setCount(count + 1)}>
Clicked {count} times
</button>
);
}
CAUTION
Never mutate state directly. Create a new value: setItems([...items, newItem]), not items.push(newItem).
Lists and keys
function TodoList({ todos }) {
return (
<ul>
{todos.map((todo) => (
<li key={todo.id}>{todo.text}</li>
))}
</ul>
);
}
Use a stable unique key (an id), not the array index when items can reorder.
Forms (controlled inputs)
function SearchBox({ onSearch }) {
const [query, setQuery] = useState("");
return (
<form
onSubmit={(e) => {
e.preventDefault();
onSearch(query);
}}
>
<input value={query} onChange={(e) => setQuery(e.target.value)} />
<button type="submit">Search</button>
</form>
);
}
Effects
useEffect runs side effects (fetching data, subscriptions) after render.
import { useEffect, useState } from "react";
function Users() {
const [users, setUsers] = useState([]);
useEffect(() => {
let cancelled = false;
fetch("/api/users")
.then((r) => r.json())
.then((data) => !cancelled && setUsers(data));
return () => { cancelled = true; }; // cleanup
}, []); // [] = run once
return <ul>{users.map((u) => <li key={u.id}>{u.name}</li>)}</ul>;
}