React
Component-based UI development with hooks, state, and the virtual DOM.
Overview
React is a JavaScript library for building user interfaces using a component-based architecture. You set up React with Node.js installed and create a project using Vite (npm create vite@latest). Components are functions that return JSX (JavaScript XML) — a syntax that looks like HTML inside JavaScript. Key concepts: Components (naming must be PascalCase), Props (data flowing parent→child), State (internal data managed with useState that triggers re-renders), and the Virtual DOM (React's lightweight copy of the real DOM that enables fast, minimal updates).
React Hooks power modern functional components. useState manages component state. useEffect handles side effects like data fetching, subscriptions, and timers — its dependency array controls when it re-runs (empty [] = once on mount). useContext provides global state without prop drilling. useRef accesses DOM elements directly without triggering re-renders. useMemo caches expensive calculations, useCallback caches function references — both prevent unnecessary re-renders in memoized child components (React.memo).
React Router (react-router-dom) handles navigation in Single Page Applications. You define routes, navigate with <Link> or useNavigate(), read URL params with useParams(), and create nested routes for shared layouts. For global state management beyond Context, Redux Toolkit (createSlice, configureStore, useSelector, useDispatch) provides a predictable state container. React apps can be deployed to Vercel or Netlify, or upgraded to Next.js for server-side rendering.
Code Example
import { useState, useEffect, useContext, createContext, useCallback } from 'react'
// Context for global theme state
const ThemeContext = createContext()
// Custom hook to fetch data
function useFetch(url) {
const [data, setData] = useState(null)
const [loading, setLoading] = useState(true)
const [error, setError] = useState(null)
useEffect(() => {
let cancelled = false
fetch(url)
.then(r => r.json())
.then(d => { if (!cancelled) { setData(d); setLoading(false) } })
.catch(e => { if (!cancelled) { setError(e.message); setLoading(false) } })
return () => { cancelled = true } // cleanup: avoid stale state
}, [url])
return { data, loading, error }
}
// A component that uses Context
function ThemeToggle() {
const { theme, setTheme } = useContext(ThemeContext)
return (
<button onClick={() => setTheme(t => t === 'light' ? 'dark' : 'light')}>
Current: {theme}
</button>
)
}
// Main App
export default function App() {
const [theme, setTheme] = useState('light')
const [query, setQuery] = useState('react')
const { data: posts, loading } = useFetch(`/api/posts?q=${query}`)
const handleSearch = useCallback((e) => {
e.preventDefault()
setQuery(e.target.search.value)
}, [])
return (
<ThemeContext.Provider value={{ theme, setTheme }}>
<div className={`app ${theme}`}>
<ThemeToggle />
<form onSubmit={handleSearch}>
<input name="search" placeholder="Search posts..." />
<button type="submit">Search</button>
</form>
{loading ? <p>Loading...</p> : (
<ul>
{posts?.map(post => (
<li key={post.id}>{post.title}</li>
))}
</ul>
)}
</div>
</ThemeContext.Provider>
)
}Test Your Knowledge
Ready to test what you've learned? Take the quiz with 10 questions and see your score.