ReactJs Daily
226 subscribers
72 photos
85 links
📢 ReactJs Daily: Ваш информационный гид в мире React! 🚀

Добро пожаловать в ReactJs Dail - канал для разработчиков, увлеченных React! Здесь вы найдете все самое важное и актуальное в экосистеме React
Download Telegram
📝 Best Practice: Использование кастомных хуков для повторного использования логики

Привет, React-разработчики! 👋 Обсудим одну из самых популярных практик для улучшения организации кода в React-приложениях — создание и использование кастомных хуков.

🔹 Что это такое?

Кастомные хуки позволяют вам выносить повторяющуюся логику из компонентов в отдельные функции. Это помогает сделать код чище, улучшить читаемость и облегчить тестирование.

По сути это обычная функция, имя которой начинается с "use", и внутри которой могут быть использованы другие хуки, такие как useState, useEffect и т.д.

🔹 Пример использования

Допустим, вам нужно использовать логику для получения данных с API в нескольких компонентах. Вместо того чтобы повторять код в каждом компоненте, можно создать хук:

import { useState, useEffect } from 'react';

// Создаем хук для загрузки данных
function useFetch(url) {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);

useEffect(() => {
async function fetchData() {
try {
const response = await fetch(url);
const result = await response.json();
setData(result);
} catch (err) {
setError(err);
} finally {
setLoading(false);
}
}
fetchData();
}, [url]);

return { data, loading, error };
}

export default useFetch;


🔹 Использование в компонентах

Теперь этот хук можно использовать в разных компонентах:

function UserList() {
const { data, loading, error } = useFetch('https://api.example.com/users');

if (loading) return <div>Loading...</div>;
if (error) return <div>Error: {error.message}</div>;

return (
<ul>
{data.map(user => (
<li key={user.id}>{user.name}</li>
))}
</ul>
);
}


🔹 Почему стоит использовать?

1. Повторное использование логики: Логику можно легко переиспользовать в разных компонентах.
2. Чистота кода: Код становится более читаемым и компактным.
3. Управление состоянием: Логику состояния можно выносить в отдельные хуки, улучшая читаемость и поддержку.
4. Легкость тестирования: Логику из хуков можно тестировать отдельно от компонентов.

🎯 Заключение

Использование кастомных хуков — это отличная практика для создания чистого, поддерживаемого и повторно используемого кода. Если у вас есть общая логика, которую вы хотите использовать в нескольких местах, обязательно подумайте о создании отдельного хука. Это сделает ваше приложение более масштабируемым и удобным для работы!

До встречи и удачного кодинга! 💻

ReactJs Daily | #shortinfo
🚀 Асинхронные хуки и работа с Suspense и Concurrent Mode в React

Привет, разработчики! 👋 Разберём продвинутые возможности React для управления асинхронными операциями — хуки и функции для удобной работы с данными, особенно когда речь идет о загрузке и обработке информации из внешних источников.

Давайте рассмотрим ключевые технологии: асинхронные хуки, Suspense и Concurrent Mode. Они позволяют улучшить производительность приложений и сделать работу с асинхронными данными более гибкой и удобной.

🔹 Suspense: Что это и зачем?

Suspense в React предназначен для того, чтобы упростить работу с асинхронными данными и улучшить их рендеринг. Suspense позволяет приостановить рендеринг компонента до тех пор, пока данные полностью не загрузятся. Это особенно полезно для отображения загрузочного состояния, так как React сам управляет задержкой рендеринга.

Пример использования:

import React, { Suspense, lazy } from 'react';

const MyComponent = lazy(() => import('./MyComponent'));

const App = () => (
<Suspense fallback={<div>Загрузка...</div>}>
<MyComponent />
</Suspense>
);


Здесь компонент MyComponent загрузится асинхронно, и до его готовности пользователь увидит fallback-заглушку. Это делает загрузку более гладкой для пользователя.

🔹 Concurrent Mode: Новый подход к рендерингу

Concurrent Mode — это обновление, которое изменяет способ рендеринга компонентов, давая React возможность прерывать рендеринг на время и возобновлять его, когда это необходимо. Concurrent Mode улучшает отзывчивость приложения, так как позволяет React перераспределять ресурсы на важные задачи.

Пример использования Concurrent Mode:

1. Используйте React.lazy() для асинхронной загрузки компонентов.
2. Включите Concurrent Mode в проекте через ReactDOM.createRoot.

import ReactDOM from 'react-dom';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);


Concurrent Mode также добавляет функцию Transition, которая помогает оптимизировать обновление состояния, давая React возможность приоритизировать задачи, которые видит пользователь, и отложить второстепенные задачи.

🔹 Асинхронные хуки: useTransition и useDeferredValue

Эти хуки добавлены для управления асинхронными операциями внутри Concurrent Mode.

- useTransition: Позволяет определить, какие обновления можно сделать приоритетными и отложить менее важные задачи.

- useDeferredValue: Используется для откладывания выполнения дорогих операций, пока у нас есть менее важные задачи.

Пример с использованием useTransition:

import { useState, useTransition } from 'react';

const App = () => {
const [value, setValue] = useState('');
const [isPending, startTransition] = useTransition();

const handleChange = (event) => {
startTransition(() => setValue(event.target.value));
};

return (
<div>
<input onChange={handleChange} placeholder="Введите текст" />
{isPending ? <p>Загрузка...</p> : <p>Результат: {value}</p>}
</div>
);
};


Здесь useTransition дает возможность управлять обновлением состояния, чтобы приложение не «зависало» при выполнении сложных операций.

🎯 Заключение

Suspense, Concurrent Mode и асинхронные хуки, такие как useTransition, — это мощные инструменты, которые делают React более гибким и отзывчивым. Они помогают управлять асинхронными операциями, улучшая пользовательский опыт и производительность вашего приложения. Попробуйте эти подходы, чтобы улучшить работу с асинхронными данными и делать свои React-приложения более удобными для пользователей!

До скорой встречи и удачи в коде! 💻

ReactJs Daily | #pro
👍2🔥1
🚀 Формы в React: Управляемые и неуправляемые компоненты

Привет, React-разработчики! 👋 Сегодня разберемся, как эффективно работать с формами. Правильное управление помогает вам получать и обрабатывать пользовательские данные, а также улучшает производительность приложения. Давайте посмотрим на основные подходы — управляемые и неуправляемые компоненты.

🔹 Управляемые компоненты

В управляемых компонентах состояние каждого поля формы контролируется самим компонентом через стейт. Это позволяет иметь полный контроль над значениями и, например, валидировать данные в реальном времени.

Пример управляемого компонента:

import { useState } from 'react';

function ControlledForm() {
const [name, setName] = useState('');

const handleChange = (e) => {
setName(e.target.value);
};

const handleSubmit = (e) => {
e.preventDefault();
console.log('Submitted name:', name);
};

return (
<form onSubmit={handleSubmit}>
<label>
Name:
<input type="text" value={name} onChange={handleChange} />
</label>
<button type="submit">Submit</button>
</form>
);
}


Плюсы управляемых компонентов:
- Простой контроль данных: React контролирует все значения, что упрощает валидацию и обработку данных.
- Синхронизация с состоянием: Вы можете синхронизировать состояние с интерфейсом, улучшая UX.

Минусы:
- Усложнение кода: При большом количестве полей в форме код может стать громоздким.
- Дополнительная нагрузка на рендер: Каждое изменение значения вызывает перерисовку компонента, что может замедлить приложение при сложных формах.

🔹 Неуправляемые компоненты

Неуправляемые компоненты, в отличие от управляемых, используют рефы для прямого доступа к DOM-элементам, без хранения состояния в React. Это упрощает обработку, особенно когда не требуется постоянная синхронизация с состоянием.

Пример неуправляемого компонента:

import { useRef } from 'react';

function UncontrolledForm() {
const nameRef = useRef();

const handleSubmit = (e) => {
e.preventDefault();
console.log('Submitted name:', nameRef.current.value);
};

return (
<form onSubmit={handleSubmit}>
<label>
Name:
<input type="text" ref={nameRef} />
</label>
<button type="submit">Submit</button>
</form>
);
}


Плюсы неуправляемых компонентов:
- Упрощенный код: Код более компактный, так как не требует состояния для каждого поля.
- Меньше рендеров: Компонент не перерисовывается при каждом изменении ввода, что делает его более производительным.

Минусы:
- Ограниченные возможности контроля: Без состояния сложнее контролировать ввод, делать проверки в реальном времени.
- Труднее валидация: Проверка данных становится сложнее, так как значения напрямую берутся из DOM.

Когда что использовать?

- Управляемые компоненты лучше подходят для форм с валидацией, когда требуется активное управление состоянием.
- Неуправляемые компоненты идеальны для простых форм или больших форм с минимальным контролем за состоянием.

🎯 Заключение

Выбор между управляемыми и неуправляемыми компонентами зависит от ваших задач. Управляемые компоненты предлагают больше контроля, но могут быть медленнее, тогда как неуправляемые более эффективны, но требуют работы с DOM напрямую. Применяйте подход, который лучше подходит для конкретного случая, и пишите формы, которые отвечают требованиям вашего приложения!

До встречи и удачного кодинга! 💻

ReactJs Daily | #begginers
👍3🫡2
🚨 Инцидент с PR в проекте Reactor 🚨

Недавно в сообществе OSS Spring произошёл интересный случай. Директор команды принял решение закрыть PR от русского разработчика в проект Reactor, сославшись на политику компании Broadcom. Это решение вызвало обсуждения и вопросы среди участников сообщества.

Однако, интересный момент: другой разработчик, также русский, но проживающий в Нидерландах, спокойно открыл PR, и его изменения были одобрены.

Как вы думаете, должны ли такие вопросы быть решены в контексте более открытого взаимодействия между разработчиками и организациями?

Вот тот самый PR

ReactJs Daily | #news
😱1
📝 Best Practices: Оптимальная архитектура проекта на React

Для создания чистой, масштабируемой архитектуры в React, следуйте этим рекомендациям:

1. Модульная структура
Группируйте компоненты по функциям (например, /features/Profile или /modules/Auth) вместо вложенных уровней, основанных на типах файлов. Это позволяет легко находить и редактировать элементы, которые отвечают за конкретные функции.

2. Разделение компонентов на UI и контейнеры
Создавайте презентационные компоненты (UI), отвечающие за внешний вид, и контейнеры, управляющие логикой. Это упрощает тестирование и делает код более предсказуемым.

3. Использование кастомных хуков
Выносите логику, которая используется в нескольких местах, в кастомные хуки. Это позволяет оптимизировать код и упрощает управление состоянием.

4. API- и сервисные слои
Все взаимодействия с API выносите в отдельные модули. Это упрощает обновления и модификацию, не затрагивая компоненты.

5. Файловая структура с логическими слоями
Добавьте папки для общих элементов (/shared), хуков (/hooks) и компонентов (/components), чтобы всегда было понятно, где искать код.

Этот подход делает ваш проект более гибким, упрощает рефакторинг и облегчает работу команде.

Пример архитектуры в комментарии.

Ставьте 👍 если вам интересно будет почитать про архитектуру Feature-Sliced Design (FSD).

ReactJs Daily | #shortinfo
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
🚀 React и TypeScript: Углубление в типизацию компонентов, пропсов и состояния

Привет! 👋 Давайте поговорим об одном из мощнейших инструментов для написания безопасного и удобного кода — TypeScript в React. Типизация делает код более предсказуемым, улучшает автодополнение и помогает избегать ошибок. В этом посте обсудим, как типизировать компоненты, пропсы и состояние, чтобы сделать код максимально надежным.

🔹 Типизация функциональных компонентов

Чтобы объявить типы для функционального компонента, используем React.FC (или React.FunctionComponent). Это базовый тип для компонентов, который включает стандартные пропсы, такие как children.

import React, { FC } from 'react';

type GreetingProps = {
name: string;
age?: number; // age — необязательный пропс
};

const Greeting: FC<GreetingProps> = ({ name, age }) => (
<div>
<p>Hello, {name}!</p>
{age && <p>Age: {age}</p>}
</div>
);

export default Greeting;


🔸 Зачем это нужно? FC автоматически типизирует children, поэтому если компонент предполагает дочерние элементы, их тип будет подхвачен TypeScript.

🔹 Типизация пропсов

TypeScript позволяет точно описывать типы для любых пропсов, делая код читаемым и предотвращая ошибки. Ниже пример с несколькими типами пропсов, включая массивы и функции.

type ListProps = {
items: string[];
onClick: (item: string) => void;
};

const ItemList: FC<ListProps> = ({ items, onClick }) => (
<ul>
{items.map((item) => (
<li key={item} onClick={() => onClick(item)}>
{item}
</li>
))}
</ul>
);


🔸 Что это дает? Мы четко указываем, что items — это массив строк, а onClick — функция, принимающая строку и ничего не возвращающая. Это уменьшает количество ошибок при передаче данных и упрощает работу с компонентом.

🔹 Типизация состояния с useState

Когда мы используем useState, TypeScript автоматически выводит тип на основе значения по умолчанию. Однако если состояние может изменять тип, его стоит задавать явно.

import React, { useState } from 'react';

const Counter: FC = () => {
const [count, setCount] = useState<number>(0);

return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
};


🔸 Зачем это нужно? Типизация count как number защищает от ошибок при передаче нечисловых значений.

🔹 Типизация ссылок с useRef

Для работы с useRef, особенно если ссылка не сразу инициализируется, полезно указать ее тип или использовать null как начальное значение.

import React, { useRef } from 'react';

const InputFocus: FC = () => {
const inputRef = useRef<HTMLInputElement | null>(null);

const focusInput = () => {
inputRef.current?.focus();
};

return (
<div>
<input ref={inputRef} type="text" />
<button onClick={focusInput}>Focus Input</button>
</div>
);
};


🔸 Зачем это нужно? Типизация useRef помогает избежать ошибок при доступе к свойствам DOM-элементов.

🔹 Типизация пользовательских хуков

Создавая собственные хуки, также можно использовать типы, чтобы управлять входными и выходными параметрами.

import { useState } from 'react';

function useToggle(initialValue: boolean): [boolean, () => void] {
const [value, setValue] = useState(initialValue);

const toggle = () => setValue((prev) => !prev);

return [value, toggle];
}

// Использование хука
const [isActive, toggleActive] = useToggle(false);


🔸 Преимущества: Четко указано, что useToggle возвращает массив с булевым значением и функцией. Это упрощает использование и предотвращает неверное использование хука.

🎯 Заключение

Типизация в React — это мощный способ повысить читаемость и надежность кода. Используйте типы для компонентов, пропсов, состояния и пользовательских хуков, чтобы сделать код безопасным и избежать неожиданных ошибок. Попробуйте применить TypeScript в ваших проектах, и увидите, как он упрощает работу!

До встречи в новых постах, и удачного кодинга! 💻

ReactJs Daily | #begginers
🚀 Введение в маршрутизацию с React Router

Привет, разработчики! Сегодня поговорим о React Router — популярной библиотеке для добавления маршрутизации в приложения React. С его помощью можно управлять навигацией, создавая многостраничные SPA (Single Page Applications) без перезагрузки страницы.

🔹 Зачем нужен React Router?
React Router позволяет переходить между различными страницами или компонентами, не перезагружая приложение. С его помощью можно создать удобные маршруты для отдельных страниц (например, Главная, Профиль, О нас) и динамические ссылки (например, /профиль/:id).

🔹 Как начать?
1. Установите библиотеку:

   npm install react-router-dom


2. Добавьте маршруты в проект:
В корневом компоненте (обычно App.js), используем <BrowserRouter>, <Routes>, и <Route> для настройки маршрутов.


   import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import Home from './pages/Home';
import Profile from './pages/Profile';

function App() {
return (
<Router>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/profile" element={<Profile />} />
</Routes>
</Router>
);
}


3. Использование Link для навигации:
React Router предоставляет компонент <Link> для навигации между страницами без перезагрузки.


   import { Link } from 'react-router-dom';

function Navbar() {
return (
<nav>
<Link to="/">Главная</Link>
<Link to="/profile">Профиль</Link>
</nav>
);
}


🔹 Динамические маршруты и параметры
С помощью динамических маршрутов можно передавать параметры URL, например, /:id.

<Route path="/profile/:id" element={<Profile />} />


Теперь компонент Profile сможет получить id через useParams:
import { useParams } from 'react-router-dom';

function Profile() {
const { id } = useParams();
return <h1>Профиль пользователя {id}</h1>;
}


🎯 Заключение
React Router — мощный инструмент для управления маршрутами в вашем приложении. Он позволяет легко организовать страницы, добавлять навигацию и создавать динамические ссылки.

ReactJs Daily | #begginers
📝 Best Practices: Управление событиями с помощью Throttling и Debouncing 🔹

Привет, разработчики! 👋 Сегодня разберём, как техники throttling и debouncing помогают управлять частотой вызова функций в React, поддерживая производительность приложений на высоком уровне. Давайте разберёмся, как это работает и когда использовать каждую из техник! 👇

🔹 Throttling
Throttling — это техника, позволяющая ограничить частоту вызова функции за определённый промежуток времени. Например, если функция привязана к событию изменения размера окна, она может вызываться непрерывно, пока пользователь двигает окно. Throttling ограничивает количество вызовов, позволяя запускать функцию, скажем, раз в 200 мс. Это снижает нагрузку на приложение и сохраняет его производительность.

Пример использования throttling для события прокрутки:

import { useCallback } from 'react';

const throttle = (func, delay) => {
let lastCall = 0;
return (...args) => {
const now = new Date().getTime();
if (now - lastCall >= delay) {
lastCall = now;
func(...args);
}
};
};

const handleScroll = () => {
console.log("Прокрутка");
};

const throttledScroll = useCallback(throttle(handleScroll, 200), []);
window.addEventListener("scroll", throttledScroll);

🔹 Debouncing
Debouncing работает немного иначе: вместо ограничения частоты вызова функция задерживается и запускается только после окончания активности. Например, если у вас есть поле поиска, и функция поиска запускается при каждом нажатии клавиши, то без debouncing может отправляться слишком много запросов. С debouncing функция срабатывает только после того, как пользователь перестал вводить текст на заданное время (например, 300 мс).

Пример использования debouncing для поиска:

import { useState, useCallback } from 'react';

const debounce = (func, delay) => {
let timer;
return (...args) => {
clearTimeout(timer);
timer = setTimeout(() => func(...args), delay);
};
};

const SearchComponent = () => {
const [query, setQuery] = useState("");

const handleSearch = useCallback(
debounce((searchText) => {
console.log("Поиск:", searchText);
// выполнить поиск
}, 300),
[]
);

const handleChange = (e) => {
setQuery(e.target.value);
handleSearch(e.target.value);
};

return <input type="text" value={query} onChange={handleChange} />;
};


🎯 Заключение
Throttling помогает уменьшить количество вызовов функций, а debouncing откладывает их до тех пор, пока активность не прекратится. Оба подхода полезны для оптимизации работы с часто происходящими событиями, такими как прокрутка, изменение размера окна и ввод текста. Используйте их, чтобы сделать ваше приложение быстрее и отзывчивее! 🚀

ReactJs Daily | #shortinfo
👍3🔥1
🚀 Поддержка веб-сокетов в React-приложениях: Реализуем реальное время с WebSocket и хуками

Веб-сокеты — отличный способ сделать ваше приложение интерактивным и обеспечить мгновенный обмен данными в реальном времени. Сегодня поговорим о том, как добавить поддержку WebSocket в React с помощью кастомных хуков!

🔹 Что такое WebSocket?
WebSocket — это протокол для двустороннего взаимодействия между клиентом и сервером в реальном времени. Он сохраняет открытое соединение, позволяя обмениваться сообщениями без повторного открытия HTTP-соединений.

🔹 Пример кастомного хука для WebSocket
Создадим хук useWebSocket для подключения к WebSocket-серверу и получения сообщений.

1. Создайте кастомный хук:


import { useEffect, useState } from 'react';

function useWebSocket(url) {
const [socket, setSocket] = useState(null);
const [message, setMessage] = useState(null);

useEffect(() => {
const ws = new WebSocket(url);
setSocket(ws);

ws.onmessage = (event) => {
setMessage(JSON.parse(event.data));
};

return () => {
ws.close();
};
}, [url]);

const sendMessage = (msg) => {
if (socket && socket.readyState === WebSocket.OPEN) {
socket.send(JSON.stringify(msg));
}
};

return { message, sendMessage };
}

export default useWebSocket;


2. Используйте хук в компоненте:


import React, { useState } from 'react';
import useWebSocket from './useWebSocket';

function Chat() {
const { message, sendMessage } = useWebSocket('ws://localhost:4000');
const [input, setInput] = useState('');

const handleSubmit = (e) => {
e.preventDefault();
sendMessage({ text: input });
setInput('');
};

return (
<div>
<h2>Чат в реальном времени</h2>
<form onSubmit={handleSubmit}>
<input
value={input}
onChange={(e) => setInput(e.target.value)}
/>
<button type="submit">Отправить</button>
</form>
{message && <p>Новое сообщение: {message.text}</p>}
</div>
);
}

export default Chat;


🔹 Как работает хук?
- useWebSocket устанавливает соединение с сервером при монтировании компонента и закрывает его при размонтировании.
- onmessage обрабатывает входящие сообщения и обновляет состояние message, чтобы его можно было использовать в компоненте.
- sendMessage отправляет данные на сервер через WebSocket.

🎯 Заключение
Использование WebSocket и кастомных хуков помогает легко добавлять реальное время в React-приложения. Вы можете использовать этот подход для чатов, уведомлений, отображения данных и других интерактивных элементов. Попробуйте создать свой хук для работы с WebSocket и добавьте живое взаимодействие в ваше приложение!

ReactJs Daily | #pro
🔥2
🚀 Обработка событий в React: Основы и Практика 🔹

Доброе утро! 👋 Сегодня поговорим о том, как эффективно работать с событиями в React, чтобы сделать интерфейсы более интерактивными и отзывчивыми. React использует собственную систему обработки событий, которая немного отличается от стандартного DOM, поэтому разберем основы и лучшие практики!

🔹 Как работают события в React?
Вместо того чтобы использовать традиционные методы addEventListener, в React мы просто добавляем атрибуты к элементам JSX, например onClick, onChange и т.д. Эти события автоматически обрабатываются через систему SyntheticEvent — это обертка над стандартными событиями браузера, которая оптимизирует их и делает кроссбраузерными.

Пример простого обработчика события:

function ClickButton() {
const handleClick = () => {
console.log("Кнопка нажата!");
};

return <button onClick={handleClick}>Нажми меня</button>;
}


🔹 Основные принципы и лучшие практики
1. Используйте стрелочные функции в обработчиках, но осторожно. Анонимные стрелочные функции в JSX создают новую функцию при каждом рендере, что может вызывать лишние рендеры у дочерних компонентов. Например:


   <button onClick={() => handleClick()} />


Вместо этого, объявляйте функции обработчиков отдельно и передавайте их:


   const handleClick = () => { ... };
<button onClick={handleClick} />


2. Передача параметров в обработчики. Если нужно передать параметры в функцию, используйте замыкания или .bind(), чтобы не создавать функции при каждом рендере:


   <button onClick={() => handleClick(param)} />  // работает, но создаёт функцию каждый раз
<button onClick={handleClick.bind(this, param)} /> // предпочтительнее


3. Предотвращайте стандартное поведение. Для обработки формы или других элементов с собственным поведением не забывайте о preventDefault().


   const handleSubmit = (e) => {
e.preventDefault();
console.log("Форма отправлена!");
};


4. Управление всплытием событий. В React всплытие событий (event bubbling) работает как в обычном DOM, поэтому будьте внимательны к обработчикам в родительских и дочерних элементах.

🔹 Комбинирование событий и состояний
События часто работают в паре с состояниями. Например, клик по кнопке может менять текст или состояние компонента:

import { useState } from 'react';

function ToggleButton() {
const [isOn, setIsOn] = useState(false);

const handleClick = () => {
setIsOn((prev) => !prev);
};

return <button onClick={handleClick}>{isOn ? "Вкл" : "Выкл"}</button>;
}


🎯 Заключение
Обработка событий — важный аспект взаимодействия с пользователем. Используйте оптимальные методы, чтобы избежать лишних рендеров и улучшить производительность!

ReactJs Daily | #begginers
👍2
📝 Best Practices: Полезная библиотека для React: React Query

Если вы работаете с данными, которые нужно получать, кешировать и обновлять, React Query — отличный инструмент! Она облегчает управление состоянием данных, делает запросы асинхронными и позволяет легко кешировать и обновлять данные.

Почему это полезно:
- Легкость: React Query позволяет меньше писать "ручного" кода для работы с API.
- Кеширование: Данные автоматически сохраняются и перезапрашиваются по мере необходимости.
- Фоновое обновление: React Query обновляет данные в фоне и моментально выводит на экран.
- Обработка ошибок: Управление ошибками проще, с встроенными опциями retry.

Пример:
import { useQuery } from 'react-query';

function MyComponent() {
const { data, error, isLoading } = useQuery('todos', fetchTodos);

if (isLoading) return <p>Загрузка...</p>;
if (error) return <p>Ошибка!</p>;

return (
<ul>
{data.map(todo => (
<li key={todo.id}>{todo.title}</li>
))}
</ul>
);
}


React Query делает взаимодействие с API гораздо удобнее и обеспечивает лучшую производительность для ваших React-приложений!

ReactJs Daily | #shortinfo
🆒4🔥3
🚀 FSD (Feature-Sliced Design) Архитектура в React: Подробное руководство по созданию структурированного проекта

Когда проект растет, правильная архитектура становится ключом к легкости поддержки и масштабирования. Feature-Sliced Design (FSD) — это подход, помогающий структурировать фронтенд-приложения так, чтобы каждая функциональность была изолирована и независима. Давайте разберем, как работает FSD и как его применять в React-проектах.

🔹 Основная идея FSD
FSD разделяет проект на уровни и модули, позволяя логично организовать компоненты, бизнес-логику и UI, основываясь на их назначении и зависимости. Благодаря этому подходу мы создаем модульные, переиспользуемые и гибкие компоненты, которые удобно тестировать, поддерживать и расширять.

🔹 Уровни FSD-архитектуры

Каждый уровень в FSD отвечает за конкретный аспект приложения:

1. App — уровень, который включает в себя инициализацию приложения. Здесь находятся:
- Основной компонент приложения (App.jsx);
- Настройки роутинга, хранилища и глобальных провайдеров (например, Redux или Context);
- Глобальные стили и настройки, например, themes.

2. Processes — глобальные процессы, которые используются в разных частях приложения:
- Например, аутентификация, обработка ошибок, конфигурация языков и локалей;
- В этом уровне организуются такие аспекты, как управление сессиями пользователя и глобальными процессами.

3. Pages — уровень, отвечающий за страницы приложения:
- Здесь организованы конкретные маршруты (pages), каждый из которых представляет собой независимый модуль (например, HomePage, ProductPage);
- В рамках страницы могут использоваться Widgets, Features и Entities;
- Этот уровень также может управлять страницами как модулями, которые обращаются к фичам и виджетам.

4. Widgets — крупные интерфейсные компоненты:
- Здесь находятся такие компоненты, как шапка (Header), подвал (Footer), боковое меню (Sidebar);
- Widgets могут содержать внутренние компоненты и подключать бизнес-логику, необходимую для их отображения, при этом избегая тяжелой логики.

5. Features — основные функциональные элементы, которые представляют отдельные действия:
- Например, фильтрация товаров (ProductFilter), добавление товара в корзину (AddToCart), формы регистрации и авторизации;
- Эти модули содержат как UI-компоненты, так и бизнес-логику, относящуюся к конкретной фиче, что делает их легко переиспользуемыми.

6. Entities — модули, которые отвечают за бизнес-логику и модель данных:
- Каждый Entity представляет сущность, например, Product, User, Order;
- Содержат взаимодействие с данными, такие как API-запросы и модели данных, что упрощает обработку данных в приложении.

7. Shared — переиспользуемые ресурсы, которые могут быть применены в разных частях проекта:
- Shared включает общие компоненты (Button, Input), стили, хелперы, хуки и утилиты;
- Эти модули предназначены для поддержки более высокого уровня компонентов, таких как Features и Widgets.

🔹 Преимущества подхода FSD

- Изоляция ответственности: FSD позволяет инкапсулировать логику и компоненты на уровне фич и виджетов, что снижает зависимость и улучшает тестируемость.
- Легкость поддержки и масштабируемость: Благодаря четкому распределению модулей, FSD подходит для проектов любой сложности, особенно если предполагается значительный рост функционала.
- Повышенная переиспользуемость: Модули, созданные на уровне Features или Shared, можно использовать повторно, что ускоряет разработку новых страниц и компонентов.
- Единая структура: С FSD легче сохранять единую структуру при добавлении новых страниц и фич, что делает проект понятным как для новых, так и для опытных разработчиков.

🎯 Заключение

Feature-Sliced Design помогает структурировать проект так, чтобы каждая часть приложения была независимой и легко изменяемой. Этот подход идеально подходит для сложных приложений, требующих четкой модульности, быстрой адаптации к изменениям и максимальной переиспользуемости компонентов.

P.S Структура в комментарии

ReactJs Daily | #pro
🚀 Управление состоянием в React-приложениях с Redux

Привет, разработчики! Сегодня обсудим одну из важнейших библиотек для управления состоянием в React — Redux. Если ваше приложение становится сложным и передача данных через пропсы вызывает неудобства, Redux может помочь в решении этих задач.

🔹 Что такое Redux и зачем он нужен?

Redux — это библиотека для управления глобальным состоянием приложения. В отличие от локального состояния, которое создается для каждого компонента отдельно (с помощью useState или useReducer), Redux позволяет хранить состояние на более высоком уровне и делиться им между всеми компонентами. Это особенно полезно в больших приложениях, где одни и те же данные должны быть доступны в разных частях интерфейса.

🔹 Основные части Redux

1. Store
Центральное хранилище всех данных приложения. Именно сюда попадают изменения состояния и откуда компоненты могут получать нужные данные.

2. Actions
Объекты, которые описывают, что именно нужно изменить в состоянии. Обычно action включает type — строку, описывающую тип изменения, и дополнительные данные (payload), если это необходимо.


const addToCart = (item) => {
return {
type: "ADD_TO_CART",
payload: item,
};
};


3. Reducers
Это чистые функции, которые описывают, как состояние изменяется в ответ на actions. Reducers не должны иметь побочных эффектов и всегда должны возвращать новое состояние.


const cartReducer = (state = [], action) => {
switch (action.type) {
case "ADD_TO_CART":
return [...state, action.payload];
case "REMOVE_FROM_CART":
return state.filter((item) => item.id !== action.payload.id);
default:
return state;
}
};


4. Dispatch
Функция, которая отправляет actions в Redux, вызывая соответствующий reducer и обновляя состояние.

🔹 Как использовать Redux в React

Для интеграции Redux с React можно воспользоваться библиотекой react-redux, которая предоставляет два основных метода: Provider и connect (или useSelector и useDispatch в случае хуков).

1. Подключение Provider
Чтобы React-компоненты могли получать данные из Redux, нужно обернуть все приложение в <Provider store={store}>, передав в него созданный store:


import { Provider } from "react-redux";
import { createStore } from "redux";
import rootReducer from "./reducers";

const store = createStore(rootReducer);

const App = () => (
<Provider store={store}>
<YourComponent />
</Provider>
);


2. Использование useSelector и useDispatch
useSelector позволяет компонентам получать данные из Redux, а useDispatch — отправлять actions.


import React from "react";
import { useSelector, useDispatch } from "react-redux";

const Cart = () => {
const cartItems = useSelector((state) => state.cart);
const dispatch = useDispatch();

const addItemToCart = (item) => {
dispatch({ type: "ADD_TO_CART", payload: item });
};

return (
<div>
<h2>Корзина:</h2>
{cartItems.map((item) => (
<p key={item.id}>{item.name}</p>
))}
<button onClick={() => addItemToCart({ id: 1, name: "Товар" })}>
Добавить товар
</button>
</div>
);
};


🔹 Когда использовать Redux?

Redux особенно полезен в проектах с большим количеством компонентов, которые разделяют и обновляют одни и те же данные. Однако для небольших приложений с ограниченным количеством состояний использование Redux может быть излишним, так как проще будет обойтись локальным состоянием React-компонентов.

🎯 Заключение

Redux помогает упорядочить состояние и облегчает управление данными в React-приложении. Его строгая структура и центральное хранилище делают приложение предсказуемым и удобным для масштабирования. Попробуйте использовать Redux в вашем проекте, и он станет незаменимым инструментом для управления состоянием в больших и сложных приложениях!

ReactJs Daily | #begginers
🤝2
📝Настройка анимаций в React: оживляем интерфейс!

Анимации делают интерфейсы React-приложений не только красивыми, но и интуитивно понятными. В React есть несколько популярных библиотек, которые помогают легко добавлять анимации, такие как Framer Motion и React Spring. Давайте рассмотрим основные примеры настройки.

🔹 Framer Motion — простой и мощный инструмент
Framer Motion позволяет легко добавлять эффекты перехода, hover-анимации, анимации при монтировании и даже сложные переходы между состояниями. Например, чтобы сделать анимацию масштаба при наведении, оборачиваем элемент в motion.div и используем свойство whileHover:

import { motion } from "framer-motion";

function Example() {
return (
<motion.div
animate={{ opacity: 1 }}
initial={{ opacity: 0 }}
transition={{ duration: 0.5 }}
whileHover={{ scale: 1.1 }}
>
Наведи на меня!
</motion.div>
);
}


🔹 React Spring — физические анимации
React Spring отлично подходит для создания анимаций, которые чувствуют себя «естественно» благодаря физике (натяжение, упругость). Подходит для сложных анимаций, таких как прокрутка и переходы между страницами:

import { useSpring, animated } from "react-spring";

function Example() {
const props = useSpring({ opacity: 1, from: { opacity: 0 } });
return <animated.div style={props}>Анимация с React Spring</animated.div>;
}


🔹 Рекомендации по использованию анимаций
- Избегайте перегрузки — много анимаций могут замедлить приложение.
- Соблюдайте последовательность — анимации должны быть гармоничными, помогать пользователю, а не отвлекать.
- Настраивайте переходы — делайте их чуть медленнее, чтобы обеспечить мягкость.

Анимации в React могут оживить интерфейс, главное — использовать их разумно. Попробуйте добавить простые эффекты, и интерфейс станет более динамичным и привлекательным для пользователей!

ReactJs Daily | #shortinfo
2
🚀 Хранилища с Zustand и Recoil: Легковесные альтернативы Redux для масштабирования приложений 🔥

Привет! 👋 В след за утренним постом про Redux, обсудим Zustand и Recoil — современные и легковесные хранилища для React, которые стали популярными благодаря своей простоте и гибкости. Если вам нужен стейт-менеджмент, но без всей сложности Redux, то эти инструменты могут стать отличной альтернативой. Давайте разберемся, как они работают и чем могут быть полезны! 👇

🔹 Zustand: Быстрый и минималистичный стейт-менеджер

Zustand — это библиотека для управления состоянием с очень простой API, которая подойдет для любых проектов, от небольших до масштабных.

Особенности:
- Простота и минимализм: Zustand не требует сложных конфигураций и шаблонного кода.
- Отсутствие лишних перерисовок: Компоненты автоматически подписываются только на нужные части состояния.
- Поддержка TypeScript: Полная типизация из коробки.

Пример использования:
import create from 'zustand';

const useStore = create((set) => ({
count: 0,
increment: () => set((state) => ({ count: state.count + 1 })),
}));

function Counter() {
const { count, increment } = useStore();
return <button onClick={increment}>Count: {count}</button>;
}


🔹 Recoil: Атомарное управление состоянием для сложных приложений

Recoil — это библиотека от Facebook, созданная для работы с состоянием в сложных и больших проектах. С Recoil можно разделять состояния на атомы, управлять зависимостями и работать с асинхронными данными.

Особенности:
- Атомарный стейт: Каждое состояние — это атом, который можно переиспользовать и комбинировать.
- Поддержка асинхронности: Встроенные селекторы позволяют управлять асинхронными операциями и кэшированием данных.
- Удобство для больших приложений: Recoil идеально подходит для сложных приложений с множеством зависимостей между состояниями.

Пример использования:
import { atom, useRecoilState } from 'recoil';

const countState = atom({
key: 'countState',
default: 0,
});

function Counter() {
const [count, setCount] = useRecoilState(countState);
return <button onClick={() => setCount(count + 1)}>Count: {count}</button>;
}


🔹 Почему Zustand и Recoil могут быть лучше Redux?

- Проще и легче настроить: Они предлагают удобное API без необходимости сложной конфигурации.
- Меньше кода: Redux требует много шаблонного кода (actions, reducers), а Zustand и Recoil — нет.
- Поддержка масштабируемости: Оба хранилища справляются с состоянием в больших приложениях.

🎯 Заключение

Zustand и Recoil — это легковесные альтернативы Redux, которые позволяют управлять состоянием, не перегружая кодовую базу. Выбирайте то, что лучше подходит вашему проекту: Zustand для легкости и быстроты, Recoil — для сложных структур и зависимостей. 🚀

Больше про Zustand - 👍
Больше про Recoil -
🔥

ReactJs Daily | #pro
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥5👍4
🚀 Интернационализация (i18n) в React: адаптируем приложение для разных языков с i18next

Привет, разработчики! 👋 Если ваш проект рассчитан на международную аудиторию, интернационализация (или i18n) — это незаменимый инструмент. С помощью i18n можно сделать так, чтобы интерфейс отображался на разных языках, улучшая пользовательский опыт и расширяя аудиторию. Сегодня разберем, как настроить i18n в React с помощью популярной библиотеки i18next.

🔹 Шаг 1: Установка и настройка i18next

Для начала установим библиотеку и её интеграцию с React:
npm install i18next react-i18next


Теперь создаем файл i18n.js для настройки. Здесь указываем языки и начальную конфигурацию:
import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';

i18n.use(initReactI18next).init({
resources: {
en: { translation: { welcome: "Welcome to our application!" }},
ru: { translation: { welcome: "Добро пожаловать в наше приложение!" }}
},
lng: "en", // Язык по умолчанию
fallbackLng: "en", // резервный язык
interpolation: { escapeValue: false },
});

export default i18n;


🔹 Шаг 2: Используем переводы в компонентах

Теперь, чтобы выводить переводимый текст, используем хук useTranslation:
import { useTranslation } from 'react-i18next';

function Welcome() {
const { t } = useTranslation();
return <h1>{t("welcome")}</h1>;
}


Здесь t("welcome") динамически выводит текст на нужном языке.

🔹 Шаг 3: Переключение языков в приложении

Чтобы пользователи могли менять язык, добавляем функцию переключения:
import i18n from "i18next";

function LanguageSwitcher() {
const changeLanguage = (lang) => i18n.changeLanguage(lang);

return (
<div>
<button onClick={() => changeLanguage("en")}>English</button>
<button onClick={() => changeLanguage("ru")}>Русский</button>
</div>
);
}


🔹 Полезные рекомендации

1. Организуйте переводы в JSON-файлы — это делает управление текстами проще.
2. Используйте ключи вместо текста, чтобы предотвратить ошибки и дублирование.
3. Поддержка fallback — если перевод отсутствует, текст отображается на основном языке.

🎯 Заключение

i18next — отличный инструмент для работы с несколькими языками в React. Благодаря ему вы легко адаптируете приложение под разные рынки, что делает его доступнее и привлекательнее для глобальной аудитории! 🌐

ReactJs Daily | #begginers
👍2
📝Best Practices: Typescript - утилитные типы для мощной типизации!

Привет, друзья! 👋 Давайте обсудим одну из самых полезных фишек TypeScript — утилитные типы. Они помогают писать более гибкий и мощный код, облегчая работу с типами и уменьшая количество повторяющегося кода. Если вы хотите максимально использовать возможности TypeScript, утилитные типы — это ваш must-have инструмент! 💪

🔹 Что такое утилитные типы?
TypeScript поставляется с набором готовых типов (Utility Types), которые помогают модифицировать существующие типы для разных задач. Они делают работу с типами более удобной и позволяют динамически изменять структуры, не создавая их с нуля.

🔹 Примеры самых популярных утилитных типов

1. `Partial<T>` — делает все поля объекта необязательными.

   type User = { id: number; name: string; age: number };
type PartialUser = Partial<User>; // { id?: number; name?: string; age?: number }


2. Pick<T, K> — выбирает определенные поля из типа.

   type User = { id: number; name: string; age: number };
type UserPreview = Pick<User, 'id' | 'name'>; // { id: number; name: string }


3. Omit<T, K> — исключает определенные поля из типа.

   type User = { id: number; name: string; age: number };
type UserWithoutAge = Omit<User, 'age'>; // { id: number; name: string }


4. ReturnType<T> — извлекает тип, возвращаемый функцией.

   function getUser() {
return { id: 1, name: 'Alice', age: 30 };
}
type UserType = ReturnType<typeof getUser>; // { id: number; name: string; age: number }


🔹 Как это помогает?
Эти типы позволяют легко менять и комбинировать существующие структуры данных, делая код чище и более читаемым. Например, если нужно создать вариант типа для редактирования или отображения данных — Partial и Pick делают это за секунды, без дублирования кода.

🎯 Заключение
Утилитные типы — это огромный плюс TypeScript, который ускоряет разработку и минимизирует ошибки. Работайте гибко и используйте весь потенциал TypeScript для создания мощных, масштабируемых приложений! 🚀

ReactJs Daily | #shortinfo
🔥3👍2
🚀 Упрощаем управление состоянием в React-приложениях с Redux Toolkit!

Вечер добрый, разработчики! 👋 Обсудим Redux Toolkit — библиотеку, которая делает работу с Redux намного проще и быстрее. Если классический Redux казался вам слишком сложным или громоздким, Redux Toolkit решает эту проблему, добавляя удобные инструменты и упрощая настройку.

🔹 Что такое Redux Toolkit?

Redux Toolkit — это официальный инструмент для более удобного и упрощенного использования Redux. Он включает мощные утилиты и автоматизирует создание экшенов и редьюсеров, благодаря чему сокращает количество шаблонного кода.

🔹 Основные функции Redux Toolkit

1. configureStore
Простая настройка стора с уже встроенными DevTools и middleware для логирования. Теперь создание стора занимает всего пару строк:


   import { configureStore } from '@reduxjs/toolkit';
import cartReducer from './cartSlice';

const store = configureStore({
reducer: {
cart: cartReducer,
},
});


2. createSlice
Это удобный метод для создания редьюсеров и экшенов одновременно. Теперь не нужно писать их отдельно, достаточно описать логику внутри слайса:


   import { createSlice } from '@reduxjs/toolkit';

const cartSlice = createSlice({
name: 'cart',
initialState: [],
reducers: {
addItem: (state, action) => {
state.push(action.payload);
},
removeItem: (state, action) => {
return state.filter((item) => item.id !== action.payload.id);
},
},
});

export const { addItem, removeItem } = cartSlice.actions;
export default cartSlice.reducer;


3. createAsyncThunk
Инструмент для обработки асинхронных действий, таких как запросы к API. Он автоматически добавляет состояния "loading", "success" и "error" для управления запросами:


   import { createAsyncThunk } from '@reduxjs/toolkit';

export const fetchProducts = createAsyncThunk(
'products/fetchProducts',
async () => {
const response = await fetch('/api/products');
return response.json();
}
);


🔹 Почему стоит использовать Redux Toolkit?

Redux Toolkit снижает сложность и избавляет от шаблонного кода, что помогает быстрее разрабатывать приложения и легче поддерживать проект. Если вы хотите использовать Redux, но всегда смущала его громоздкость, Redux Toolkit — идеальное решение.

А так же в нём есть очень крутая штука RTK Query — это мощный инструмент из Redux Toolkit для работы с данными из API в React-приложениях. Он автоматизирует процесс запроса, кеширования, обновления данных и синхронизации состояния. RTK Query особенно полезен для приложений, которые часто взаимодействуют с сервером, так как он берет на себя управление состоянием загрузки, успешными ответами и ошибками. С ним запросы к API можно настраивать буквально в пару строк!

Пример настройки запроса:

import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';

export const api = createApi({
reducerPath: 'api',
baseQuery: fetchBaseQuery({ baseUrl: '/api' }),
endpoints: (builder) => ({
getProducts: builder.query({
query: () => '/products',
}),
}),
});

export const { useGetProductsQuery } = api;


RTK Query избавляет от необходимости вручную прописывать логику работы с API, делая код чище и упрощая поддержку приложения.

🎯 Заключение

Redux Toolkit — это мощный инструмент, который помогает быстрее развернуть и поддерживать состояние в React-приложении. Попробуйте интегрировать его в ваш проект и насладитесь удобством и быстротой работы с Redux!


P.S. На текущей работе как раз используем rtk query, невероятно мощная и удобная штука.

ReactJs Daily | #pro
👍4🆒2
🚀 Как использовать Context API для шаринга состояния без Redux?

Привет! 👋 Недавно мы обсуждали управление состоянием с помощью Redux и Redux Toolkit, но сегодня давайте разберём альтернативный подход — Context API в React, который тоже помогает работать с глобальным состоянием. Context API — встроенный инструмент в React для шаринга состояния между компонентами, минуя передачу через пропсы.

🔹 Что такое Context API?
Context API позволяет передавать данные напрямую из одного компонента в другой, минуя промежуточные уровни. Это полезно, когда нужно, чтобы состояние, например, тема или авторизация, было доступно сразу во всём приложении. Контекст делает приложение проще и избавляет от «пробрасывания пропсов» (props drilling).

🔹 Как использовать Context API для управления глобальным состоянием?
Context API удобно использовать для шаринга небольших данных. Давайте создадим простой контекст и посмотрим, как его можно настроить:

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

const ThemeContext = createContext();

const ThemeProvider = ({ children }) => {
const [theme, setTheme] = useState('light');
return (
<ThemeContext.Provider value={{ theme, setTheme }}>
{children}
</ThemeContext.Provider>
);
};

const useTheme = () => useContext(ThemeContext);


Теперь каждый компонент, использующий useTheme(), будет иметь доступ к данным theme и функции setTheme:

const ThemedButton = () => {
const { theme, setTheme } = useTheme();
return (
<button onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}>
Переключить тему
</button>
);
};


🔹 Когда использовать Context API?
Context API подходит для небольших проектов или для состояний, которые не требуют масштабного управления, как в Redux. Это простой способ сделать глобальное состояние доступным, не добавляя зависимости в виде Redux.

🎯 Заключение
Context API — это встроенное решение в React, которое упрощает шаринг данных. В крупных приложениях или при сложной логике состояния Redux или Redux Toolkit могут быть более удобными, но для простых задач Context API отлично подходит, не перегружая приложение лишними зависимостями.

ReactJs Daily | #begginers
🔥2
📝 Продолжаем изучение контекста в React: useContextSelector 🚀

В предыдущем посте мы обсуждали, как эффективно использовать Context API. А сейчас разберем, как useContextSelector может еще больше оптимизировать работу с контекстом, позволяя подписываться только на определенные значения, а не на весь контекст.

🔹 Зачем useContextSelector?
При использовании стандартного useContext любое изменение контекста приводит к ререндеру всех компонентов, его использующих. useContextSelector решает эту проблему, позволяя подписываться только на выбранные части данных. Это снижает нагрузку и улучшает производительность, особенно при работе с большими данными.

🔹 Как использовать useContextSelector?

1. Установка:

npm install use-context-selector



2. Пример:

import { createContext, useContextSelector } from 'use-context-selector';

const UserContext = createContext();

function UserProvider({ children }) {
const [user, setUser] = useState({ name: 'Андрей', age: 30 });
return (
<UserContext.Provider value={{ user, setUser }}>
{children}
</UserContext.Provider>
);
}

function UserName() {
// Только подписка на имя пользователя
const name = useContextSelector(UserContext, (context) => context.user.name);
return <p>Имя: {name}</p>;
}

function UserAge() {
// Только подписка на возраст пользователя
const age = useContextSelector(UserContext, (context) => context.user.age);
return <p>Возраст: {age}</p>;
}


Теперь компоненты UserName и UserAge будут ререндериться только при изменении соответствующих данных.

🎯 Заключение: useContextSelector — мощный инструмент для работы с контекстом в React, позволяющий оптимизировать производительность.

ReactJs Daily | #shortinfo
👍3🔥3