Learning React Hooks: A Simple Guide for Nepali Beginners

React Hooks

I’m a senior full-stack developer who has worked on everything from small applications to large-scale systems for companies around the world. Today, I want to help you, as a Nepali beginner, understand React Hooks in a simple, practical way.

We will keep the language clear and the examples realistic. Think of this as a calm conversation over tea in Kathmandu, without jargon or unnecessary complexity.

If you are new to React, you may have heard about class components. While they work, they become difficult to manage as an application grows. Before learning Hooks, it is important to understand why they were introduced.


The Problem with Class Components

Imagine building a simple todo application using class components. State is handled like this:

this.state = { count: 0 };
this.setState({ count: this.state.count + 1 });

This approach works for small examples, but problems appear as the application becomes more complex.

Logic related to a single feature is spread across multiple lifecycle methods such as componentDidMount, componentDidUpdate, and componentWillUnmount. Code becomes harder to read, logic is duplicated, and bugs become more common. For beginners, this structure often feels overwhelming.

React Hooks were introduced to solve these problems.


What Are React Hooks?

Hooks are functions that allow you to use React features such as state and side effects inside functional components. They were introduced in React version 16.8 and are now the standard way of writing React applications.

With Hooks, you no longer need classes. Components become simple JavaScript functions with logic grouped in one place.

Modern applications built with React rely heavily on Hooks for clean and maintainable code.


useState: Managing Component State

Before Hooks, state could only be used in class components. The useState Hook allows functional components to manage state easily.

You should use useState whenever data changes over time, such as counters, form inputs, or lists.

Basic Syntax

import { useState } from ‘react’;
const [value, setValue] = useState(initialValue);

The first variable stores the current state. The second variable is a function used to update it. Updating state causes the component to re-render.

Example: Counter Component

import { useState } from ‘react’;
function Counter() {
const [count, setCount] = useState(0);
return (
<>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>
Add
</button>
</>
);
}

In real applications, useState can be used to track likes on blog posts or product quantities in an e-commerce cart.


useEffect: Handling Side Effects

Side effects include actions such as fetching data, setting up timers, or subscribing to events. Previously, these were handled using lifecycle methods. The useEffect Hook keeps related logic together.

You should use useEffect whenever something needs to happen after the component renders.

Basic Syntax

import { useEffect } from ‘react’;
useEffect(() => {
// side effect
return () => {
// cleanup
};
}, [dependencies]);

Example: Timer

import { useState, useEffect } from ‘react’;
function Timer() {
const [seconds, setSeconds] = useState(0);
useEffect(() => {
const interval = setInterval(() => {
setSeconds(prev => prev + 1);
}, 1000);
return () => clearInterval(interval);
}, []);
return <p>Seconds: {seconds}</p>;
}

In real-world applications, useEffect is commonly used to fetch blog posts, load user profiles, or retrieve product data.


useMemo: Optimizing Performance

By default, React recalculates everything on each render. This can slow down your application when heavy calculations are involved.

The useMemo Hook allows React to remember the result of a calculation and recompute it only when its dependencies change.

Example: Expensive Calculation

import { useState, useMemo } from ‘react’;
function ExpensiveList() {
const [numbers] = useState([1, 2, 3, 4]);
const sum = useMemo(() => {
return numbers.reduce((a, b) => a + b, 0);
}, [numbers]);
return <p>Sum: {sum}</p>;
}

This approach is useful for filtering large lists, calculating totals, or processing search results.


useCallback: Preventing Unnecessary Re-renders

In JavaScript, functions are recreated on every render. When these functions are passed to child components, they can cause unnecessary re-renders.

The useCallback Hook memoizes a function so that it only changes when its dependencies change.

Example: Stable Callback

import { useState, useCallback } from ‘react’;
function Parent() {
const [count, setCount] = useState(0);
const handleClick = useCallback(() => {
setCount(prev => prev + 1);
}, []);
return <Child onClick={handleClick} />;
}
function Child({ onClick }) {
return <button onClick={onClick}>Click me</button>;
}

This is particularly important in large applications and performance-sensitive components.


useRef: Accessing the DOM and Mutable Values

Sometimes you need direct access to a DOM element or need to store a value that does not trigger a re-render. The useRef Hook is designed for this purpose.

Example: Focusing an Input

import { useRef } from ‘react’;
function TextInput() {
const inputRef = useRef(null);
const focusInput = () => {
inputRef.current.focus();
};
return (
<>
<input ref={inputRef} />
<button onClick={focusInput}>Focus</button>
</>
);
}

This technique is commonly used for input focus management, scroll position tracking, and storing previous values.


Other Useful React Hooks

  1. useContext for sharing global data without prop drilling
  2. useReducer for managing complex state logic
  3. useLayoutEffect for DOM measurements
  4. useId for generating unique accessibility IDs
  5. useTransition and useDeferredValue for smoother UI updates

There is no need to master all of these at once. Start with the fundamentals and expand gradually.


Putting It All Together: Product List Example

import { useState, useEffect, useMemo, useRef } from ‘react’;
function ProductList() {
const [products, setProducts] = useState([]);
const [search, setSearch] = useState(”);
const listRef = useRef(null);
useEffect(() => {
fetch(‘https://api.example.com/products’)
.then(res => res.json())
.then(setProducts);
}, []);
const filteredProducts = useMemo(() => {
return products.filter(p =>
p.name.toLowerCase().includes(search.toLowerCase())
);
}, [products, search]);
useEffect(() => {
if (listRef.current) {
listRef.current.scrollTop = 0;
}
}, [search]);
return (
<>
<input
value={search}
onChange={e => setSearch(e.target.value)}
placeholder=”Search products”
/>
<ul ref={listRef} style={{ height: 200, overflow: ‘auto’ }}>
{filteredProducts.map(p => (
<li key={p.id}>
{p.name} – ${p.price}
</li>
))}
</ul>
</>
);
}

This example demonstrates how multiple Hooks work together in a real application.


Final Advice for Beginners

React Hooks make code simpler, cleaner, and easier to maintain. If you are learning React today, you can skip class components entirely and focus on Hooks.

Start with small projects such as a todo app, a simple blog, or a basic e-commerce page. Practice consistently, even if only for a short time each day.

Progress in programming is steady, not instant. Keep learning, keep building, and you will get there.

Share this article:
Leave a Comment

Leave a Reply

Your email address will not be published. Required fields are marked *