Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 54 additions & 25 deletions lessons/lesson32/lesson.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,13 @@ const handleMouseLeave = () => setIsHovered(false);

<!-- v -->

HOC
HOC (Higher-Order Components)

- Функция, которая принимает компонент и возвращает новый компонент
- Позволяет добавлять логику "снаружи"
- Используется для переиспользования поведения

<!-- v -->

```jsx
function withHover(WrappedComponent) {
Expand All @@ -78,8 +84,27 @@ export default withHover(MyComponent);

<!-- v -->

Плюсы:

- Разделение обязанностей (UI отдельно, логика отдельно)
- Легко оборачивать несколько компонентов

Минусы:

- "Wrapper hell" (дерево компонентов сильно усложняется)
- Возможны конфликты props
- Логика скрыта внутри обёртки

<!-- v -->

Render Props

- Компонент принимает функцию как child
- Эта функция управляет тем, что будет отрисовано
- Позволяет гибко делиться состоянием и поведением

<!-- v -->

```jsx
function Hover({ children }) {
const [isHovered, setIsHovered] = useState(false);
Expand All @@ -106,14 +131,20 @@ function App() {

<!-- v -->

Оба подхода рабочие, но имеют недостатки:
Плюсы:

- "Wrapper Hell": Дерево компонентов разрастается за счет оберток.
- Неявные зависимости: Сложно понять, откуда приходят props.
- Конфликты имен: Props от разных HOC могут перезаписывать друг друга.
- Гибкость — родитель решает, как отрисовать
- Чёткий контроль над данными

Минусы:

- Синтаксис иногда "шумный"
- Легко создать "пирамиду функций"

<!-- v -->

Оба подхода рабочие, но имеют недостатки

Хуки предложили более элегантное решение.

<!-- v -->
Expand Down Expand Up @@ -218,26 +249,25 @@ function UserProfile() {
Создаем хук useRequest

```jsx
Копировать код
import { useState, useEffect } from 'react';
import { useState, useEffect } from "react";

export function useRequest(url) {
const [data, setData] = useState(null);
const [isLoading, setIsLoading] = useState(true);
const [error, setError] = useState(null);

useEffect(() => {
if (!url) return;

setIsLoading(true);
fetch(url)
.then(res => res.json())
.then(data => setData(data))
.catch(err => setError(err))
.finally(() => setIsLoading(false));
}, [url]);

return { data, isLoading, error };
const [data, setData] = useState(null);
const [isLoading, setIsLoading] = useState(true);
const [error, setError] = useState(null);

useEffect(() => {
if (!url) return;

setIsLoading(true);
fetch(url)
.then((res) => res.json())
.then((data) => setData(data))
.catch((err) => setError(err))
.finally(() => setIsLoading(false));
}, [url]);

return { data, isLoading, error };
}
```

Expand Down Expand Up @@ -267,10 +297,9 @@ function UserProfile({ userId }) {
хук useInput

```jsx
Копировать код
function useInput(initial = "") {
const [value, setValue] = useState(initial);
const onChange = e => setValue(e.target.value);
const onChange = (e) => setValue(e.target.value);
return { value, onChange };
}
```
Expand Down