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

Добро пожаловать в ReactJs Dail - канал для разработчиков, увлеченных React! Здесь вы найдете все самое важное и актуальное в экосистеме React
Download Telegram
🚀 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
📝 Оптимизация обработчиков событий в React: минимизация ререндера и делегирование событий

Почему это важно?
Обработчики событий могут стать причиной замедления приложения, особенно если вы добавляете их на множество элементов. Лишние рендеры или неэффективная обработка событий могут повлиять на производительность.

Советы

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

Плохо:
<button onClick={() => console.log("Клик!")}>Клик</button>


Хоршо:
const handleClick = () => console.log("Клик!");

<button onClick={handleClick}>Клик</button>



2. Используйте `useCallback` для мемоизации функций:
Когда обработчик передается как пропс в дочерний компонент, мемоизируйте его с помощью хука useCallback, чтобы сохранить одну и ту же ссылку между рендерами.

const handleClick = useCallback(() => {
console.log("Клик!");
}, []);



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

Пример:
const handleClick = (event) => {
if (event.target.tagName === "BUTTON") {
console.log(`Кнопка с текстом "${event.target.textContent}" нажата`);
}
};

return (
<div onClick={handleClick}>
<button>Кнопка 1</button>
<button>Кнопка 2</button>
</div>
);


В этом примере обработчик добавлен только на родительский элемент, а не на каждую кнопку.

Результат:
Делегирование событий и правильное использование useCallback помогут вам оптимизировать работу приложения, уменьшить количество обработчиков и предотвратить лишние рендеры.

ReactJs Daily | #shortinfo
👍1🤝1