Skip to content

React

Компоненты

export default function Button() {
return <button>Click me</button>;
}

Вставка переменных в шаблон

export const HomePage = () => {
const number = 8;
function fibonacci(n) {
if (n <= 1) return 1;
return fibonacci(n - 1) + fibonacci(n - 2);
}
return (
<div>
<p>Это число: {number}</p>
<p>Это число умноженное на 2: {number * 2}</p>
<p>Это число фибоначчи: {fibonacci(number)}</p>
</div>
);
};

Рендеринг коллекций

export const HomePage = () => {
const students = [
{ id: 1, fullName: "John", age: 20, gpa: 3.5 },
{ id: 2, fullName: "Jane", age: 21, gpa: 3.7 },
{ id: 3, fullName: "Bob", age: 19, gpa: 3.2 },
{ id: 4, fullName: "Alice", age: 22, gpa: 3.8 },
];
return (
<div>
<h1>Студенты</h1>
<ul>
{students.map((student) => (
<li key={student.id}>
{student.fullName} - {student.age} лет, {student.gpa} GPA
</li>
))}
</ul>
</div>
);
};

Props

interface ButtonProps {
children: React.ReactNode;
onClick: () => void;
}
export default function Button(props: ButtonProps) {
return <button onClick={props.onClick}>{props.children}</button>;
}

Hooks

useState

import { useState } from "react";
const Counter = () => {
const [count, setCount] = useState(0); // count — текущее значение, setCount — функция обновления
return (
<div>
<p>Счетчик: {count}</p>
<button onClick={() => setCount(count + 1)}>+</button>
</div>
);
};

useEffect

1. Запуск эффекта при каждом рендере (без зависимостей)

import { useState, useEffect } from "react";
function Counter() {
const [count, setCount] = useState(0);
useEffect(() => {
console.log("Компонент обновился!");
});
return (
<div>
<p>Счетчик: {count}</p>
<button onClick={() => setCount(count + 1)}>Увеличить</button>
</div>
);
}

🔍 Что происходит?

  • useEffect вызывается после каждого рендера (в том числе после обновления состояния count).
  • В консоли после каждого клика будет сообщение “Компонент обновился!”.

🔴 Минус: может вызывать ненужные вычисления, если эффект не должен запускаться при каждом рендере.

2. Запуск эффекта один раз (при монтировании компонента)

Если передать пустой массив зависимостей [], эффект выполнится только один раз – при первом рендере.

import { useEffect } from "react";
function HelloWorld() {
useEffect(() => {
console.log("Компонент был смонтирован!");
}, []);
return <p>Привет, мир!</p>;
}

🔍 Что происходит?

  • Сообщение “Компонент был смонтирован!” появится только один раз после монтирования.

📌 Применение:

  • Запрос данных (fetch)
  • Подписка на глобальные события (window.addEventListener)
  • Установка начального состояния (localStorage.getItem)

3. Запуск эффекта при изменении зависимостей

Если передать массив зависимостей, эффект будет срабатывать только при изменении этих зависимостей.

import { useState, useEffect } from "react";
function UserProfile({ userId }) {
const [userData, setUserData] = useState(null);
useEffect(() => {
console.log(`Загружаем данные для пользователя ${userId}`);
fetch(`https://jsonplaceholder.typicode.com/users/${userId}`)
.then((response) => response.json())
.then((data) => setUserData(data));
}, [userId]); // Запускается только при изменении userId
return <p>Пользователь: {userData?.name || "Загрузка..."}</p>;
}

🔍 Что происходит?

  • useEffect сработает при первом рендере и каждый раз, когда изменяется userId.
  • Если userId не меняется — эффект не выполняется повторно.

📌 Применение:

  • Переключение между пользователями (например, при выборе ID)
  • Запрос новых данных при изменении параметров
  • Обновление стилей или заголовков страницы

4. Очистка эффекта (Cleanup)

Некоторые эффекты (например, таймеры или подписки) требуют очистки перед размонтированием компонента или перед повторным вызовом эффекта.

import { useState, useEffect } from "react";
function Timer() {
const [seconds, setSeconds] = useState(0);
useEffect(() => {
const interval = setInterval(() => {
setSeconds((prev) => prev + 1);
}, 1000);
return () => {
clearInterval(interval); // Очистка таймера при размонтировании
console.log("Таймер остановлен!");
};
}, []); // Таймер запускается только при монтировании
return <p>Секунды: {seconds}</p>;
}

🔍 Что происходит?

  • setInterval запускается при монтировании.
  • Когда компонент размонтируется, вызывается clearInterval, чтобы предотвратить утечки памяти.

📌 Применение:

  • Отписка от событий (window.removeEventListener)
  • Очистка таймеров (clearTimeout, clearInterval)
  • Закрытие соединений (WebSocket, AbortController)

5. Очистка перед каждым новым вызовом

Если эффект зависит от переменной, React сначала очистит предыдущий эффект перед вызовом нового.

import { useState, useEffect } from "react";
function MouseTracker() {
const [position, setPosition] = useState({ x: 0, y: 0 });
useEffect(() => {
const updateMousePosition = (event) => {
setPosition({ x: event.clientX, y: event.clientY });
};
window.addEventListener("mousemove", updateMousePosition);
return () => {
window.removeEventListener("mousemove", updateMousePosition);
console.log("Очистка: отписка от mousemove");
};
}, []);
return (
<p>
Координаты мыши: {position.x}, {position.y}
</p>
);
}

🔍 Что происходит?

  • При монтировании подписка window.addEventListener(“mousemove”, updateMousePosition).
  • Если компонент размонтируется, вызывается removeEventListener, чтобы избежать утечек памяти.

📌 Применение:

  • Отписка от глобальных событий
  • Удаление старых подписок перед добавлением новых
  • Завершение анимаций или запросов

useRef

import { useRef } from "react";
function Counter() {
const countRef = useRef(0);
useEffect(() => {
console.log(countRef.current);
}, [countRef.current]);
return (
<div>
<p>Счетчик: {countRef.current}</p>
<button onClick={() => countRef.current++}>+</button>
</div>
);
}