FediScanner

#react

← Back

What Are React Hooks?


A Hook is a function that lets a component use a React feature. useState lets it remember a value. useEffect lets it do something after it shows up on the screen, like starting a timer. useContext lets it read shared data. Every Hook name starts with use, which makes them easy to spot.

Before Hooks, these features only worked inside class components, with constructors, this, and lifecycle methods like componentDidMount. Hooks give you the same abilities in a plain function, and the code comes out shorter and easier to follow.

Why Beginners Should Learn Hooks


Almost everything you'll read or write today uses them. The React docs, Next.js, and most libraries are built around function components, so classes are something you mostly see in old code. Hooks also remove a lot of boilerplate, since there are no classes, no constructors, and no binding methods. They make reuse easy too. If two components need the same behavior, you move it into a custom Hook once and use it in both. And the newest React features, like form Actions and optimistic updates, are built on Hooks, so learning them now means you're ready for those as well.

The Complete Guide


React Hooks changed how we write React apps. Before them, if a component needed state, or had to do something after it appeared on the screen, you had to write a class. Now a plain function can do all of that, and you can share the same logic between components without any tricks.

This guide covers all the stable React Hooks, from the basic ones to the newer ones that arrived with React 19. The examples use plain React and Next.js, and every Hook gets a short explanation plus code you can copy. If you're new, read it from the top. If you already know the basics, skip ahead to the section on new Hooks.

As of right now, the latest stable release is React 19.3, which dropped on September 9, 2026. This version finally makes ViewTransition and Fragment Refs stable. Even though neither of these is actually a Hook, I've covered both near the end of this guide since you'll definitely start seeing them pop up in newer codebases. Everything discussed below works perfectly fine on React 19, but if a specific Hook requires a newer minor version, I'll be sure to point it out.

The plan is simple. First the core Hooks, then the additional ones, then the advanced ones. After that come the Hooks added in React 19 and later, the Hooks that belong to Next.js, custom Hooks, common mistakes, and a cheatsheet you can keep open while you code.

Table of Contents


  • What Are React Hooks?
  • Why Beginners Should Learn Hooks
  • Core Hooks
    • useState
    • useEffect
    • useContext


  • Additional Hooks
    • useRef
    • useMemo
    • useCallback
    • useReducer


  • Advanced Hooks
    • useLayoutEffect
    • useImperativeHandle
    • useId



Core Hooks


useState

useState simply lets your component remember data.When you use it, you get the current value and a function to change it.

What is a Render?
Think of a render as React refreshing or redrawing the screen. It is just React running your component function to see what should change visually.

How it works:
You call the function to update the data.This tells React: "Hey, the data changed!"React instantly renders (re-runs) the component to show the new data on your screen.

'use client';

import { useState } from 'react';

export default function LikeButton() {
const [likes, setLikes] = useState(0);

return (
<button onClick={() => setLikes((current) => current + 1)}>
Likes: {likes}
</button>
);
}

Notice how we use setLikes((current) => current + 1). When your new state depends on the old state, always pass a function like this. This ensures React always uses the absolute latest value, even if multiple updates happen at the exact same time.Here are two important rules that beginners often miss:Lazy Initialization (For heavy tasks): If setting up your starting value takes a lot of work (like reading from localStorage or filtering a huge list), don't run it directly inside useState. Instead, pass a function like useState(() => getHeavyData()). React will run this function only once on the very first render.State Immutability (Never edit state directly): Never update an object or an array directly (like user.name = 'Alex'). React only checks if the overall object reference has changed. If you modify it directly, React won't notice the change and your screen won't update. Always make a fresh copy using the spread operator: setUser({ ...user, name: 'Alex' }).

Note: It's a good fit for counters, toggles, form inputs, and any small piece of UI state.

useEffect

useEffect is used for things that happen outside of the normal rendering process—like fetching data, starting timers, listening to the window, or using browser tools. React runs your effect right after the component shows up on the screen.
The list of brackets [] at the end is the dependency array. It simply tells React exactly when to run that code again.

What is Fetching?
Fetching just means asking a server or an external API for data over the internet (like getting a list of users, weather info, or product details) so you can show it on your app.

How it works:
Empty array []: Runs only once when the component first appears.With values [props.id]: Runs again only when those specific values change.

'use client';

import { useEffect, useState } from 'react';

export default function WindowWidth() {
const [width, setWidth] = useState(0);

useEffect(() => {
function handleResize() {
setWidth(window.innerWidth);
}

handleResize();
window.addEventListener('resize', handleResize);

return () => window.removeEventListener('resize', handleResize);
}, []);

return <p>Window width: {width}px</p>;
}

Whatever you return inside useEffect is your cleanup function. React calls it right before running the effect again, and also when the component disappears from the screen.

Always clean up things like timers and event listeners. If you don't, they will keep running in the background and slow down your app (this is called a memory leak).

Why does my code run twice?
In development, React uses Strict Mode, which intentionally runs your effect twice. It does this just to test if your cleanup function is working properly. If you see your console.log appearing twice, that is exactly why!

Next.js detail: effects run only in the browser, never on the server. So the first HTML is built with your starting state, which is 0 here, and the effect fixes it once the page loads. A simple rule to follow is that if you can work something out while rendering, do it right there and skip the effect.

useContext

useContext reads shared data from the nearest provider above your component. It saves you from passing the same prop down through many layers, which people call prop drilling. Themes, the logged in user, and the language setting are the classic uses.

'use client';

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

const ThemeContext = createContext({ theme: 'light', setTheme: () => {} });

export function ThemeProvider({ children }) {
const [theme, setTheme] = useState('light');

return (
<ThemeContext value={{ theme, setTheme }}>
{children}
</ThemeContext>
);
}

export function ThemeToggle() {
const { theme, setTheme } = useContext(ThemeContext);

return (
<button onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}>
Current theme: {theme}
</button>
);
}

React 19 lets you use the context itself as the provider, so does the job of . Also remember that every component reading the context renders again when the value changes, so keep fast changing data out of one big shared context.

In the Next.js App Router, put the provider in a file that starts with 'use client', then wrap children with it inside layout.js. The pages inside can still be Server Components.

Additional Hooks


useRef

Think of useRef as a little storage box. It holds onto a value between renders, but changing that value never triggers a re-render (it won't refresh the screen).

Developers use it for two main things:

Grabbing a DOM element: Like directly focusing an input box or scrolling to a specific part of the page.

Holding background data: Like storing a timer ID or tracking how many times a user clicked a button without needing to change what is shown on the screen.

'use client';

import { useRef } from 'react';

export default function SearchBox() {
const inputRef = useRef(null);

return (
<>
<input ref={inputRef} placeholder="Search products" />
<button onClick={() => inputRef.current.focus()}>Focus the box</button>
</>
);
}

In React 19 a function component can receive ref as a normal prop, so new code doesn't need forwardRef. Try not to read or write ref.current while rendering. Do it inside event handlers or effects.

useMemo

useMemo simply remembers the result of a heavy calculation so React doesn't have to do the math all over again on every render. It only recalculates when the data it depends on changes.

Think of it like this:
Use it for heavy work: Like filtering through thousands of users or sorting a massive list.

Skip it for small work: If you are just filtering 10 or 20 items, don't use it. The extra code overhead isn't worth it.

'use client';

import { useMemo, useState } from 'react';

export default function ProductSearch({ products }) {
const [query, setQuery] = useState('');

const matches = useMemo(() => {
return products.filter((product) =>
product.name.toLowerCase().includes(query.toLowerCase())
);
}, [products, query]);

return (
<>
<input value={query} onChange={(e) => setQuery(e.target.value)} />
<p>{matches.length} products found</p>
</>
);
}

useCallback

useCallback does the exact same job as useMemo, but for functions instead of calculation results.

Normally, React creates your functions completely fresh on every single render. If you pass that function down to a child component, the child thinks it received a brand-new prop and updates itself, even if nothing actually changed.

useCallback stops this by remembering the function between renders.

Why it matters:
Think of an item list (like a shopping basket) with an Add Button:

Without useCallback, typing a single letter in the search box re-creates the "add" function. This forces the Add Button to re-render needlessly.

With useCallback, the "add" function stays the same in memory. Typing in the input refreshes the basket, but the Add Button stays completely untouched, skipping unnecessary work.

'use client';

import { memo, useCallback, useState } from 'react';

const AddButton = memo(function AddButton({ onAdd }) {
console.log('AddButton rendered');
return <button onClick={onAdd}>Add one</button>;
});

export default function Basket() {
const [count, setCount] = useState(0);
const [note, setNote] = useState('');

const handleAdd = useCallback(() => {
setCount((current) => current + 1);
}, []);

return (
<>
<input value={note} onChange={(e) => setNote(e.target.value)} />
<p>Items: {count}</p>
<AddButton onAdd={handleAdd} />
</>
);
}

Don't add these two everywhere. They clutter the code, and measuring first saves you from fixing problems you don't have. Also, React Compiler has reached version 1.0 and is no longer experimental, and when you switch it on it adds this kind of memoization for you at build time. In newer projects you'll write useMemo and useCallback much less than older tutorials suggest.

useReducer

useReducer is great when you have a component with complex state logic, or when multiple pieces of state need to update together at the same time. Instead of having many scattered useState calls, it keeps all your state logic in one single place.

Here is how it works in two simple steps:
The Action: You tell React what happened by sending an action with a clear label, like "added", "deleted", or "cleared".

The Reducer: A special function (the reducer) looks at that label and handles the math to decide exactly what the new state should be.

'use client';

import { useReducer } from 'react';

function cartReducer(state, action) {
switch (action.type) {
case 'added':
return [...state, action.item];
case 'removed':
return state.filter((item) => item.id !== action.id);
case 'cleared':
return [];
default:
throw new Error('Unknown action: ' + action.type);
}
}

export default function Cart() {
const [items, dispatch] = useReducer(cartReducer, []);

return (
<div>
<button
onClick={() =>
dispatch({ type: 'added', item: { id: Date.now(), name: 'Book' } })
}
>
Add book
</button>
<button onClick={() => dispatch({ type: 'cleared' })}>Clear</button>
<p>{items.length} items in cart</p>
</div>
);
}

The reducer has to be a pure function. The same input always gives the same output, and it never fetches data or makes random values. That also makes it easy to test without rendering anything.

Advanced Hooks

It looks exactly like useEffect, but runs earlier: right after React updates the DOM structure, but before the browser draws anything on the screen.

  • When to use: Use it only when you need to measure an element (like its height or width) and immediately change the UI based on that measurement. Using a normal useEffect here might cause a quick, annoying layout flicker.
  • Warning: It blocks the browser from drawing, so keep the code inside small. For everything else, stick to useEffect.

'use client';
import { useLayoutEffect, useRef, useState } from 'react';

export default function MeasuredBox({ children }) {
const boxRef = useRef(null);
const [height, setHeight] = useState(0);

useLayoutEffect(() => {
// Measures the exact height before the screen draws
setHeight(boxRef.current.getBoundingClientRect().height);
}, []);

return (
<div ref={boxRef}>
{children}
<small>Box height: {height}px</small>
</div>
);
}

useImperativeHandle

Normally, parents talk to child components via props. But sometimes, a parent needs to trigger a method inside the child directly (like calling .focus() or .clear() on a custom input). useImperativeHandle lets the child component expose specific functions to the parent through a ref.

  • Note: In React 19, ref is a normal prop, so you don't need forwardRef anymore.

'use client';
import { useImperativeHandle, useRef } from 'react';

function FancyInput({ ref }) {
const inputRef = useRef(null);

// Decide exactly what methods the parent can call
useImperativeHandle(ref, () => ({
focus() { inputRef.current.focus(); },
clear() { inputRef.current.value = ''; }
}));

return <input ref={inputRef} />;
}

export default function Form() {
const fancyRef = useRef(null);

return (
<>
<FancyInput ref={fancyRef} />
<button onClick={() => fancyRef.current.focus()}>Focus</button>
<button onClick={() => fancyRef.current.clear()}>Clear</button>
</>
);
}

useId

This hook generates a unique, stable ID. It is essential for linking form fields with labels (htmlFor={id}).

  • Why use it? If you generate IDs with Math.random(), the server-rendered HTML and browser-rendered HTML won't match, causing Next.js to crash with a hydration mismatch error (Hydration is when React attaches itself to the server's HTML). useId keeps the ID identical on both sides.
  • Rule: Never use it to generate keys for item lists.

'use client';
import { useId } from 'react';

export default function EmailField() {
const id = useId();

return (
<>
<label htmlFor={id}>Email</label>
<input id={id} type="email" />
</>
);
}#react #tutorial #javascript #nextjs #software #coding #development #engineering #inclusive #community
React Hooks Made Simple: The Complete Guide, Part-1

Show Original PostReport

React Hooks


Hooks are special functions in React that allow functional components to use React features such as state. Before hooks were introduced, state and other React features were mainly used with class components. Hooks made it possible to use these features inside functional components in a simpler way.

A hook is usually a function that starts with the word use. Some commonly used hooks are useState, useEffect, and useContext. Each hook has a specific purpose. useState is used to store and update data that can change inside a component.

useState


useState is a React hook used to create a state variable in a functional component. It returns two values: the current state value and a function used to update that value.

import { useState } from "react";

function App() {
const [count, setCount] = useState(0);

return (
<div>
<h1>Count: {count}</h1>

<button onClick={() => setCount(count + 1)}>
+
</button>
</div>
);
}

Here, count stores the current value and setCount changes the value. The 0 passed to useState is the initial value.

useState can also be used with different types of data. For example:

const [name, setName] = useState("");
const [isVisible, setIsVisible] = useState(false);
const [likes, setLikes] = useState(0);

When the state is updated, React re-renders the component and displays the updated value.

For input fields, useState can store the value entered by the user:

const [name, setName] = useState("");

<input
value={name}
onChange={(event) => setName(event.target.value)}
/>

event.target.value gets the current value from the input and setName updates the state.

State can also control whether something is displayed:

const [isVisible, setIsVisible] = useState(false);

<button onClick={() => setIsVisible(!isVisible)}>
Show / Hide
</button>

{isVisible && <p>Hello!</p>}

Here, the boolean state controls the visibility of the paragraph.

Think of it as:
If isVisible is true, show <p>Hello!</p>. Otherwise, show nothing.

Ex:
{false && <p>Hello!</p>} The paragraph is not displayed.
{true && <p>Hello!</p>} React displays: Hello!

This is called conditional rendering using the "&&" operator.

useState is useful whenever a component needs to remember changing information, such as counters, input values, likes, messages, or whether an element should be visible.#react #webdev #programming #javascript #software #coding #development #engineering #inclusive #community
React Hooks And useState

Show Original PostReport

От localStorage к HttpOnly Cookie. Как меняется архитектура авторизации в SPA

В большинстве SPA-авторизация до сих пор строится вокруг JWT, localStorage и заголовка Authorization. Такой подход прост и удобен, но он заставляет клиентское приложение самостоятельно управлять credential и пользовательской сессией. В этой статье разберём, что меняется при переходе на HttpOnly Cookie и серверные сессии: как браузер хранит и отправляет Cookie, зачем нужны HttpOnly, Secure, SameSite, Domain и Path, и почему вместе с Cookie приходится по-новому смотреть на CSRF и CORS. Отдельно разберём разницу между JWT и session ID внутри Cookie, а в практической части посмотрим, как такая архитектура меняет React-приложение с Axios и MobX.

habr.com/ru/companies/gnivc/ar

#httponly #httponly_cookie #localstorage #spa #аутентификация #авторизация_пользователя #react #mobx #reactjs #архитектура

Show Original PostReport

Калькулятор плитки: фото вместо цвета и 3D, который наконец не бесит

Всем привет, это третья часть, в которой пилю калькулятор плитки - tilely.ru . Получился довольно крупный патч, в основном вокруг 3D-режима, и там оказалось прилично багов. Многое пришлось переделывать из того, что сначала казалось логичным, а на практике оказалось вообще неудобным. Перед самим 3D - то, что допилил ещё раньше в очереди. Теперь можно загружать фото плитки, чтобы не смотреть на однотипные прямоугольники одного цвета. Есть кнопка «применить ко всем комнатам». Если у вас, скажем, санузел и кухня одной плиткой идут, не надо грузить фото дважды. Так же теперь можно выбирать цвет швов, а то они были всегда одного цвета, и картинка порой сливалась.

habr.com/ru/articles/1086120/

#калькулятор_плитки #ремонт #плитка #обрезки #3d #threejs #react #konva #canvas #diy

Show Original PostReport