Components, useState, useEffect, and modern patterns.
Function componentsexport default function Card({ title, children }) { return <div className="card"><h2>{title}</h2>{children}</div>; }JSX expressions {}{isLoggedIn ? <Dashboard/> : <Login/>} | {count > 0 && <Badge n={count}/>}key prop in lists{posts.map(p => <Post key={p.id} data={p}/>)}Fragment <>...</>return <><li>First</li><li>Second</li></>;Portal: createPortalreturn createPortal(<Modal/>, document.getElementById('modal-root'));Error boundariesclass EB extends React.Component { componentDidCatch(e,i){log(e)} render(){ return this.state.err ? <Fallback/> : this.props.children } }Compound components<Tabs><Tabs.List><Tabs.Tab>One</Tabs.Tab></Tabs.List><Tabs.Panel>Content</Tabs.Panel></Tabs>useState(init)const [count, setCount] = useState(0); setCount(prev => prev + 1);useEffect(fn, deps)useEffect(() => { const sub = store.subscribe(update); return () => sub.unsubscribe(); }, [store]);useRef(initial)const prevProps = useRef(props); useEffect(() => { prevProps.current = props; });useCallback(fn, deps)const handleClick = useCallback(() => dispatch({type:'INC'}), [dispatch]);useMemo(fn, deps)const sorted = useMemo(() => [...items].sort(cmp), [items]);useReducer(reducer, init)const [state, dispatch] = useReducer(reducer, {count:0, status:'idle'});useContext(Context)const { user, logout } = useContext(AuthContext);useId()const id = useId(); return <><label htmlFor={id}>Name</label><input id={id}/></>;useTransition / useDeferredValueconst [isPending, startTransition] = useTransition(); startTransition(() => setFilter(input));useImperativeHandle + forwardRefuseImperativeHandle(ref, () => ({ focus: () => inputRef.current.focus() }));useSyncExternalStoreconst width = useSyncExternalStore(store.subscribe, store.getSnapshot, store.getServerSnapshot);React.memo(Component)const List = React.memo(({ items }) => ..., (prev, next) => deepEqual(prev.items, next.items));Custom hooks conventionfunction useLocalStorage(key, init) { const [v, setV] = useState(() => JSON.parse(localStorage.getItem(key)) ?? init); ... }Suspense + lazy()const Chart = lazy(() => import('./Chart')); <Suspense fallback={<Spinner/>}><Chart/></Suspense>use() hook (React 19)const user = use(fetchUserPromise); // suspends while pendingContext + useReducerconst StateCtx = createContext(); export const useStore = () => useContext(StateCtx);Zustand patternconst useStore = create(set => ({ count: 0, inc: () => set(s => ({count: s.count+1})) }));Lifting state up// Parent: const [tab, setTab] = useState(); // Pass setTab to child A, tab to child BDerived state (selector)const totalPrice = useMemo(() => cart.reduce((s,i) => s+i.price, 0), [cart]);Optimistic UI updatessetItems(prev => [...prev, optimistic]); await api.save(); // revert in catchReact Query / TanStack Queryconst { data, isLoading } = useQuery({ queryKey: ['post', id], queryFn: () => fetchPost(id) });Profiler component<Profiler id="Nav" onRender={(id,phase,actual) => console.log(id,actual)}><Nav/></Profiler>Why did you Render (dev)MyComp.whyDidYouRender = true; // logs every unnecessary re-renderReact Testing Libraryconst btn = screen.getByRole('button', {name: /submit/i}); await userEvent.click(btn);act() wrapperawait act(async () => { await userEvent.click(submitBtn); });