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

Добро пожаловать в ReactJs Dail - канал для разработчиков, увлеченных React! Здесь вы найдете все самое важное и актуальное в экосистеме React
Download Telegram
📝 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
ReactJs Daily
🚀 Хранилища с Zustand и Recoil: Легковесные альтернативы Redux для масштабирования приложений 🔥 Привет! 👋 В след за утренним постом про Redux, обсудим Zustand и Recoil — современные и легковесные хранилища для React, которые стали популярными благодаря своей…
🚀 Часть 1: Введение в Recoil и работа с атомами

Recoil — это легковесная библиотека для управления глобальным состоянием в React. Разработанная Facebook, она направлена на решение задач, с которыми разработчики сталкиваются при работе с React Context API или Redux. Recoil позволяет легко организовать состояние, избегая лишних рендеров и упрощая доступ к данным.

Преимущества Recoil:
1. Гибкость — Recoil позволяет структурировать состояния в атомах и селекторах, что облегчает масштабирование.
2. Оптимизация рендеров — подписка на атомы позволяет перерисовывать только нужные компоненты.
3. Простота работы с асинхронными операциями — Recoil имеет встроенную поддержку для запросов к API.

🔹 Начальная настройка Recoil
Чтобы использовать Recoil в проекте, начнем с установки библиотеки:

npm install recoil


Теперь обернем все приложение в <RecoilRoot>, который предоставляет доступ к Recoil-состоянию:

// index.js или App.js
import React from 'react';
import ReactDOM from 'react-dom';
import { RecoilRoot } from 'recoil';
import App from './App';

ReactDOM.render(
<RecoilRoot>
<App />
</RecoilRoot>,
document.getElementById('root')
);


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

🔹 Основные концепции: атомы

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

Создание атома

// atoms.js
import { atom } from 'recoil';

export const todoListState = atom({
key: 'todoListState', // уникальный ключ
default: [], // начальное значение
});


Здесь мы создали todoListState, который будет хранить массив задач.

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

// TodoList.js
import React from 'react';
import { useRecoilState } from 'recoil';
import { todoListState } from './atoms';

function TodoList() {
const [todos, setTodos] = useRecoilState(todoListState);

const addTodo = () => {
setTodos([...todos, { id: todos.length + 1, text: 'Новая задача' }]);
};

return (
<div>
<h3>Список задач:</h3>
<ul>
{todos.map(todo => (
<li key={todo.id}>{todo.text}</li>
))}
</ul>
<button onClick={addTodo}>Добавить задачу</button>
</div>
);
}

export default TodoList;


Здесь useRecoilState используется для подписки на todoListState. Теперь todos будет обновляться при изменениях todoListState, и компонент автоматически перерисуется.

🔹 Дополнительные хуки для атомов
- useRecoilValue: если нужно только прочитать значение атома, используйте useRecoilValue. Он возвращает текущее значение атома.
- useSetRecoilState: если нужно только установить значение атома (без чтения), используйте useSetRecoilState.

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

import React from 'react';
import { useRecoilValue, useSetRecoilState } from 'recoil';
import { todoListState } from './atoms';

function TodoItem({ todo }) {
const todos = useRecoilValue(todoListState);
const setTodos = useSetRecoilState(todoListState);

const removeTodo = (id) => {
setTodos(todos.filter(todo => todo.id !== id));
};

return (
<div>
<p>{todo.text}</p>
<button onClick={() => removeTodo(todo.id)}>Удалить</button>
</div>
);
}


🎯Заключение к первой части

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

Огоньков было больше, поэтому начнем с Recoil 😊

ReactJs Daily | #pro
🔥43🆒2
🚀 Роутинг в React с React Router: Продвинутые техники

Утро доброе! Сегодня разберем, как создать гибкий и мощный роутинг в React-приложениях с помощью React Router. Я уже рассказывал ранее как установить эту библиотеку и начать пользоваться, поэтому в этом посте погрузимся в продвинутые техники, которые помогут организовать маршруты более эффективно.

🔹 Вложенные маршруты
Вложенные маршруты позволяют создавать многоуровневую структуру страниц, когда один маршрут содержит в себе другие. Это особенно полезно для создания страниц с подстраницами (например, панель администрирования или профили пользователей).

import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import Layout from './components/Layout';
import HomePage from './pages/HomePage';
import ProfilePage from './pages/ProfilePage';
import Settings from './pages/Settings';
import Orders from './pages/Orders';

function App() {
return (
<Router>
<Routes>
<Route path="/" element={<Layout />}>
<Route index element={<HomePage />} />
<Route path="profile" element={<ProfilePage />}>
<Route path="settings" element={<Settings />} />
<Route path="orders" element={<Orders />} />
</Route>
</Route>
</Routes>
</Router>
);
}


Здесь <Route path="/" element={<Layout />}> создает базовую оболочку, а вложенные маршруты для ProfilePage определяют подстраницы для Settings и Orders.

🔹 Динамические параметры
React Router позволяет передавать динамические параметры в URL, чтобы рендерить разные компоненты в зависимости от параметров.

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

function UserProfile() {
const { userId } = useParams();
return <div>Профиль пользователя: {userId}</div>;
}


Параметры
(например, userId) можно использовать для рендеринга уникальной информации. Настраивается такой маршрут легко:

<Route path="user/:userId" element={<UserProfile />} />


Теперь, если вы перейдете по /user/123, в компонент UserProfile попадет userId со значением 123.

🔹 Защита маршрутов
Защищенные маршруты нужны, чтобы ограничить доступ к определенным страницам для незарегистрированных пользователей или тех, у кого нет прав доступа.

Создадим компонент ProtectedRoute, который проверяет авторизацию:

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

function ProtectedRoute({ children, isAuthenticated }) {
return isAuthenticated ? children : <Navigate to="/login" />;
}


Теперь мы можем обернуть защищенные маршруты:

<Route
path="profile"
element={
<ProtectedRoute isAuthenticated={isAuthenticated}>
<ProfilePage />
</ProtectedRoute>
}
/>


ProtectedRoute
проверяет, авторизован ли пользователь, и если нет — перенаправляет его на страницу входа.

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

ReactJs Daily | #begginers
👍7🔥2
📝 Советы по работе с датами в React

Работа с датами — это задача, с которой сталкивается почти каждый разработчик. Вот несколько полезных советов, чтобы сделать этот процесс проще и эффективнее:

1. Используйте проверенные библиотеки
Библиотеки, такие как date-fns, Day.js или Luxon помогут с форматированием, расчетами и локализацией. Они позволяют легко выполнять сложные операции с датами.

import { format } from "date-fns";

const today = new Date();
console.log(format(today, "yyyy-MM-dd")); // 2024-11-15


2. Храните даты в формате ISO 8601
Стандартный формат YYYY-MM-DDTHH:mm:ss.sssZ подходит для хранения и передачи данных через API. Он упрощает работу с часами, минутами и часовыми поясами.

3. Работайте с локализацией
Если приложение поддерживает несколько языков, используйте локализацию для отображения дат. Например, с Intl.DateTimeFormat или библиотеками вроде date-fns можно форматировать даты под нужный регион.

const formatter = new Intl.DateTimeFormat("ru-RU", { dateStyle: "long" });
console.log(formatter.format(new Date())); // 15 ноября 2024 г.


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

import { addDays } from "date-fns";

const nextWeek = addDays(new Date(), 7);
console.log(nextWeek); // Дата через 7 дней


5. Учитывайте часовые пояса
Для работы с пользователями из разных регионов используйте инструменты, поддерживающие работу с часовыми поясами, например, Luxon.

6. Проверяйте входящие данные
Если даты приходят из API, всегда валидируйте их формат и преобразуйте к универсальному виду.

const isValidDate = (date) => !isNaN(new Date(date).getTime());
console.log(isValidDate("2024-11-15")); // true
console.log(isValidDate("Неправильная дата")); // false


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

ReactJs Daily | #shortinfo
👍31
ReactJs Daily
🚀 Часть 1: Введение в Recoil и работа с атомами Recoil — это легковесная библиотека для управления глобальным состоянием в React. Разработанная Facebook, она направлена на решение задач, с которыми разработчики сталкиваются при работе с React Context API…
🚀 Часть 2: Селекторы в Recoil — вычисляемое состояние и работа с зависимостями

Привет, друзья! 👋 В первой части мы обсудили атомы в Recoil — основу для управления состоянием. Сегодня поговорим о селекторах — мощном инструменте для вычисления производных данных и работы с зависимостями.

🔹 Что такое селекторы?
Селекторы в Recoil — это функции, которые вычисляют состояние на основе атомов или других селекторов. Они позволяют извлекать, фильтровать или комбинировать данные, не изменяя сами атомы.

Представьте, что у вас есть список задач, и вы хотите получить только завершенные. Селектор сделает это за вас!

🔹 Как создать селектор
Селекторы создаются с помощью selector из Recoil. Вы передаете объект с ключом и функцией get, которая описывает, как извлечь или вычислить данные.

Пример:

import { atom, selector } from "recoil";

// Атом: список задач
const tasksState = atom({
key: "tasksState",
default: [
{ id: 1, text: "Учить Recoil", completed: true },
{ id: 2, text: "Сделать проект", completed: false },
],
});

// Селектор: завершенные задачи
const completedTasksSelector = selector({
key: "completedTasksSelector",
get: ({ get }) => {
const tasks = get(tasksState);
return tasks.filter((task) => task.completed);
},
});


🔹 Использование селекторов
Вы можете использовать селектор в компонентах так же, как атомы, через useRecoilValue.

import { useRecoilValue } from "recoil";

function CompletedTasks() {
const completedTasks = useRecoilValue(completedTasksSelector);

return (
<ul>
{completedTasks.map((task) => (
<li key={task.id}>{task.text}</li>
))}
</ul>
);
}


Результат: в списке будут только завершенные задачи.

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

Например, вы можете комбинировать несколько атомов:

const userState = atom({
key: "userState",
default: { name: "Алексей", age: 30 },
});

const userInfoSelector = selector({
key: "userInfoSelector",
get: ({ get }) => {
const user = get(userState);
return `${user.name}, ${user.age} лет`;
},
});


Теперь любое изменение в userState автоматически обновит значение userInfoSelector.

🔹 Асинхронные селекторы
Селекторы поддерживают асинхронные операции, такие как запросы к API. Просто возвращайте Promise из функции get.

const userDataSelector = selector({
key: "userDataSelector",
get: async () => {
const response = await fetch("https://api.example.com/user");
const data = await response.json();
return data;
},
});


🎯 Заключение

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


Будет 3-я часть😌

ReactJs Daily | #pro
👍1
🚀 Server Components в React 19: Новый подход к рендерингу

Привет, разработчики! Сегодня поговорим про React Server Components (RSC) — одну из ключевых новых возможностей React 19, которая помогает оптимизировать производительность и упрощает работу с данными.

`
🔹 Что такое Server Components?
Server Components — это способ рендерить React-компоненты на сервере, а не на клиенте. Вместо передачи полного HTML или JSON сервер возвращает "React-структуры" (внутреннее представление компонентов), которые затем рендерятся на клиенте.

Идея в том, чтобы перенести сложную логику (например, загрузку данных) на сервер, оставив клиенту только обновление UI. Это позволяет:
- Уменьшить размер бандла на клиенте.
- Повысить производительность за счет рендеринга тяжелых компонентов на сервере.
- Снизить количество запросов к API с клиента.


🔹 Как это работает?
В React-компоненте, который вы хотите рендерить на сервере, достаточно указать async перед функцией.
Пример:
// Серверный компонент
export default async function ServerComponent() {
const data = await fetchData(); // Логика загрузки данных на сервере
return <div>Данные: {data}</div>;
}

Этот компонент обрабатывается сервером, а его результат передается клиенту.

🔹 Преимущества Server Components
1. Меньший объем JS на клиенте.
Только UI-компоненты остаются на клиенте, а тяжелая логика работает на сервере.

2. Мгновенная доступность данных.
Загрузка данных происходит на сервере, и клиент получает уже готовый результат без лишних запросов.

3. Повышение безопасности.
Логика работы с секретными данными остается на сервере, исключая их утечку на клиент.


🔹 Использование Server Components вместе с Client Components
React позволяет сочетать Server и Client Components для максимальной гибкости. Например:
// App.jsx
import ClientComponent from './ClientComponent';
import ServerComponent from './ServerComponent';

export default function App() {
return (
<div>
<ServerComponent />
<ClientComponent />
</div>
);
}

Server Components
будут рендериться на сервере, а Client Components останутся на клиенте.


🔹 Ограничения Server Components
- Нельзя использовать хуки React, которые зависят от браузерного окружения (например, useState или useEffect).
- Не предназначены для взаимодействия с DOM напрямую.


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

Попробуйте использовать Server Components в своем следующем проекте и оцените их преимущества!

ReactJs Daily | #begginers
3