VOOZH about

URL: https://dev.to/gihan_benaragama/the-5-react-hooks-every-beginner-must-know-2kde

⇱ The 5 React hooks every beginner must know - DEV Community


A hook is just a special function in React that lets you "hook into" React features from inside a regular function component

In this post

  1. useState — remembering things
  2. useEffect — reacting to changes
  3. useContext — sharing data everywhere
  4. useRef — grabbing DOM elements
  5. useMemo & useCallback — staying fast

Hooks were introduced in React 16.8 and completely changed how we write components. Instead of complex class-based components, we now write simple functions and "hook into" React features. Let's go through the five you'll use every single day.

1. useState

  • Lets your component remember a value — and update the UI when that value changes.

Think of it like a scoreboard. When a player scores, the number on the board updates automatically. useState is your scoreboard — it holds a value, and when it changes, React re-renders the component

// Import the useState Hook from React
import { useState } from 'react'

// Define a functional component named Counter
function Counter() {

 // useState(0):
 // - Creates a state variable called "count"
 // - Creates a function called "setCount" to update "count"
 // - Initializes count with the value 0
 const [count, setCount] = useState(0)

 // Return the JSX (UI) that will be rendered
 return (
 <div>
 {/* Display the current value of count */}
 <p>You clicked {count} times</p>

 {/* 
 When the button is clicked:
 1. Read the current value of count
 2. Add 1 to it
 3. Update the state using setCount()
 4. React re-renders the component with the new value
 */}
 <button onClick={() => setCount(count + 1)}>
 {/* Text shown on the button */}
 Click me
 </button>
 </div>
 )
}

// Export the component so it can be imported into other files
export default Counter

Real-world uses

  • Form inputs - Keep track of what the user is typing into an email or password field.
  • Like button - Store the liked state and toggle it — exactly like a Twitter/X heart button.

Key rule: Never modify state directly (e.g. count = count + 1). Always use the setter function (setCount) so React knows to re-render

2. useEffect — reacting to changes

  • Runs code after your component renders — perfect for fetching data, setting up subscriptions, or talking to the outside world.

Think of it like a notification trigger. When something happens (component loads, a value changes), a side effect kicks in — like fetching fresh data from an API.

// Import the useState and useEffect Hooks from React
import { useState, useEffect } from 'react'

// Define a functional component named WeatherApp
function WeatherApp() {

 // Create a state variable named "weather"
 // Initial value is null because no weather data has been loaded yet
 const [weather, setWeather] = useState(null)

 // useEffect runs after the component renders
 useEffect(() => {

 // Fetch weather data from the API
 fetch('https://api.weather.com/today')

 // Convert the response into JSON format
 .then(res => res.json())

 // Store the fetched data in the weather state
 .then(data => setWeather(data))

 }, []) // Empty dependency array [] means:
 // Run this effect only once when the component first mounts

 // If weather is still null, show a loading message
 if (!weather) {
 return <p>Loading...</p>
 }

 // Once weather data is available, display the temperature
 return (
 <p>It is {weather.temp}°C today</p>
 )
}

// Export the component so it can be used in other files
export default WeatherApp

Avoid infinite loops: If you update state inside useEffect without a dependency array, it will keep running forever. Always add the [] or specific dependencies

3. useContext — sharing data everywhere

  • Lets any component access shared data — without passing props through every level of the tree

  • Think of it like a WiFi network. You set up a router (the context provider) once, and any device in range (any child component) can connect and get the internet — without running a cable from device to device

import { createContext, useContext, useState } from 'react'

// Create a Context object (shared data container)
const ThemeContext = createContext()

function App() {
 // State to store the current theme
 const [theme, setTheme] = useState('light')

 return (
 // Provide theme and setTheme to all child components
 <ThemeContext.Provider value={{ theme, setTheme }}>
 <Navbar />
 <Page />
 </ThemeContext.Provider>
 )
}

function Navbar() {
 // Consume (read) values from ThemeContext
 const { theme, setTheme } = useContext(ThemeContext)

 return (
 // Toggle between 'light' and 'dark' themes
 <button onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}>
 Toggle theme: {theme}
 </button>
 )
}

Real-world uses

  • Dark mode - Share the current theme across every component without passing it as a prop everywhere.
  • Logged-in user - Once the user logs in, share their name and profile across the entire app.
  1. useRef — grabbing DOM elements
  • Gives you a direct reference to a DOM element — or stores a value that doesn't trigger a re-render when it changes.

Think of it like a sticky note on a physical object. You stick a label on an input box, and later you can point to it directly — without going through React's re-render cycle.

import { useRef } from 'react'

function SearchBar() {
 // Create a ref object. Initially, current is null.
 const inputRef = useRef(null)

 function handleClick() {
 // Access the actual <input> DOM element and place the cursor inside it
 inputRef.current.focus()
 }

 return (
 <div>
 {/* Attach the ref to the input DOM element */}
 <input ref={inputRef} placeholder="Search..." />

 {/* When clicked, call handleClick to focus the input */}
 <button onClick={handleClick}>Focus search</button>
 </div>
 )
}

Real-world uses

  • Auto-focus - Focus a login input the moment a modal opens — better UX without re-rendering.
  • Store a timer ID - Save setTimeout's return value so you can cancel it later — without triggering a re-render.

useState vs useRef: Use useState when changing the value should update the UI. Use useRef when you just need to remember a value or grab a DOM element — no UI update needed.

5. useMemo & useCallback — staying fast

  • Cache expensive calculations or functions so React doesn't redo them on every render.

Think of it like mental notes. If someone asks you "what's 1247 × 38?" you calculate it once and remember the answer. If they ask again with the same numbers — you just give the answer from memory instead of recalculating

import { useState, useMemo } from 'react'

function ProductList({ products }) {
 // State to store the user's search text
 const [search, setSearch] = useState('')

 // Memoize the filtered list and recalculate it
 // only when products or search changes
 const filtered = useMemo(() => {
 return products.filter(p =>
 p.name.toLowerCase().includes(search.toLowerCase())
 )
 }, [products, search])

 return (
 <div>
 {/* Controlled input: value comes from state and updates state on typing */}
 <input
 value={search}
 onChange={e => setSearch(e.target.value)}
 />

 {/* Render only the filtered products */}
 {filtered.map(p => (
 <p key={p.id}>{p.name}</p>
 ))}
 </div>
 )
}
import { useCallback } from 'react'

function Parent() {
 // Memoize the function and keep the same function reference
 // between renders unless dependencies change
 const handleClick = useCallback(() => {
 console.log('button clicked!')
 }, []) // [] = create the function once and reuse it on every render

 // Pass the memoized function to the child component
 return <ExpensiveButton onClick={handleClick} />
}
  • useMemo — filtered / sorted lists
    Filtering 10,000 products every keypress is expensive. Cache the result until the data or search term changes.

  • useCallback — stable event handlers
    When passing a function to a child component wrapped in React.memo, keep the same reference to prevent unnecessary re-renders.

Don't over-use these. Wrapping everything in useMemo / useCallback adds its own cost. Only use them when you notice actual performance problems — measure first.

Quick reference summary

  1. useState - Store & update UI values
  2. useEffect - Side effects a fter render
  3. useContext - Share data app-wide
  4. useRef - Access DOM elements
  5. useMemo - Cache expensive values
  6. useCallback - Cache functions

Master these five and you'll be able to build almost any React app. The rest of the hooks exist for more specific or advanced scenarios — but these are the foundation. Happy coding! 🚀