React + TypeScript Basics
React is the most popular frontend library in the world. Combined with TypeScript, you get type-safe, maintainable UI code. This week we build the frontend that talks to your Spring Boot API.
React: You write components that describe what the UI should look like for a given state. When state changes, React automatically figures out the minimal DOM changes needed. You think about state, not DOM manipulation.
| Old Way (Vanilla JS) | React Way |
|---|---|
| Manually update DOM | Declare what UI looks like, React handles DOM |
| State scattered in variables | State managed declaratively with useState |
| Reuse via copy-paste | Reusable components |
| Hard to test | Components are testable functions |
Key files in the project
className instead of class (class is a reserved word in JS). Every component must return a single root element (or use <></> fragment). Components start with a Capital letter.count = count + 1. Always use the setter function: setCount(count + 1). Direct mutation won't trigger a re-render.@CrossOrigin(origins = "http://localhost:5173") to your Spring controller, or configure CORS globally in WebMvcConfigurer.React is a JavaScript library for building user interfaces using reusable components. Instead of manually manipulating the DOM, you declare what the UI should look like for a given state, and React handles updates efficiently via its Virtual DOM.
Benefits: reusable components, predictable state management, huge ecosystem, excellent performance via virtual DOM diffing, strong TypeScript support.
Props (properties) are passed FROM parent TO child โ they're read-only. A child component cannot modify its own props.
State is managed WITHIN a component using useState. It's the component's own memory. When state changes, the component re-renders.
Rule: if data is needed by multiple components, lift state up to their common parent and pass it down as props.
useEffect runs side effects after rendering. "Side effects" are operations outside the normal render cycle: API calls, subscriptions, DOM manipulation, timers.
The second argument (dependencies array) controls when it runs:
useEffect(() => {...}, [])โ runs once after first render (on mount)useEffect(() => {...}, [userId])โ runs when userId changesuseEffect(() => {...})โ runs after EVERY render (rarely needed)
TypeScript adds static typing to JavaScript. With React + TypeScript:
- Define the shape of props with interfaces โ get compile-time errors if you pass wrong types
- API response types are explicit โ no guessing what fields exist
- Better IDE autocomplete and refactoring support
- Errors caught at compile time, not at runtime in production
CORS (Cross-Origin Resource Sharing) is a browser security mechanism that blocks frontend code from calling a different origin (different protocol, domain, or port).
React (localhost:5173) calling Spring Boot (localhost:8080) = different ports = CORS error.
Fix in Spring Boot: Add @CrossOrigin annotation on controllers, or configure globally with a CORS configuration bean that allows your frontend's origin.