- Set — для хранения уникальных значений, без повторений.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍15🔥8
Это процесс снижения количества лишних перерисовок компонентов, что улучшает производительность приложения. React повторно рендерит компоненты, когда их состояние (
state
) или свойства (props
) изменяются. Однако часто это приводит к ненужным рендерам, которые можно избежать.Чем больше компонентов рендерится без необходимости, тем больше времени тратится на вычисления и обновления DOM.
Избегая лишних рендеров, приложение работает быстрее, а пользовательский интерфейс становится более отзывчивым.
Плавная работа интерфейса критична для сложных приложений с большим количеством данных.
React предоставляет утилиту
React.memo
, чтобы предотвращать ререндеринг компонента, если его props
не изменились.import React from 'react';
const MyComponent = React.memo(({ count }) => {
console.log('Рендер компонента');
return <div>Счётчик: {count}</div>;
});
// Использование
export default function App() {
const [count, setCount] = React.useState(0);
return (
<div>
<MyComponent count={count} />
<button onClick={() => setCount(count + 1)}>Увеличить</button>
</div>
);
}
Эти хуки используются для предотвращения повторных вычислений и создания функций при каждом рендере.
import React, { useMemo } from 'react';
function ExpensiveCalculationComponent({ number }) {
const calculatedValue = useMemo(() => {
console.log('Выполняются сложные вычисления...');
return number ** 2;
}, [number]); // Пересчитывается только если `number` изменился
return <div>Результат: {calculatedValue}</div>;
}
Пример
useCallback
import React, { useCallback, useState } from 'react';
const Child = React.memo(({ onClick }) => {
console.log('Рендер дочернего компонента');
return <button onClick={onClick}>Кликни меня</button>;
});
function Parent() {
const [count, setCount] = useState(0);
const handleClick = useCallback(() => {
console.log('Кнопка нажата');
}, []); // Создаётся одна и та же функция между рендерами
return (
<div>
<Child onClick={handleClick} />
<button onClick={() => setCount(count + 1)}>Увеличить {count}</button>
</div>
);
}
Использование
React.lazy
и Suspense
позволяет загружать компоненты только тогда, когда они необходимы.import React, { Suspense } from 'react';
const LazyComponent = React.lazy(() => import('./LazyComponent'));
function App() {
return (
<Suspense fallback={<div>Загрузка...</div>}>
<LazyComponent />
</Suspense>
);
}
Избегайте запуска побочных эффектов, если зависимости не изменились.
React.useEffect(() => {
console.log('Эффект сработал!');
}, [/* следите только за нужными зависимостями */]);
Передача новых объектов и функций через
props
вызывает лишние рендеры.<ChildComponent data={{ key: 'value' }} />
Лучше так
const data = { key: 'value' };
<ChildComponent data={data} />;
Если компонент слишком сложный, разделите его на более мелкие, чтобы React мог эффективно управлять состоянием и перерисовкой.
Каждый элемент списка должен иметь уникальный ключ, чтобы React мог правильно отслеживать изменения.
{items.map(item => (
<div key={item.id}>{item.name}</div>
))}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13❤10🔥1
- useLayoutEffect вызывается перед отрисовкой, после внесения изменений в DOM, что позволяет выполнить синхронные действия, такие как измерение DOM.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍23🔥11
Это популярная концепция в программировании, особенно в функциональных языках и библиотеках вроде RxJS (в контексте реактивного программирования). Она используется для последовательного применения функций к данным.
pipe
работает с чистыми функциями, которые не изменяют исходные данные и возвращают новый результат. Это повышает предсказуемость кода.Вместо вложенных вызовов функций (когда результат одной функции передается в другую)
pipe
упрощает цепочку, делая её линейной.Код становится проще для понимания, особенно если функций много.
Можно легко добавлять или удалять шаги в цепочке, не меняя структуру кода.
pipe
принимает несколько функций в качестве аргументов и применяет их слева направо к переданным данным. То есть результат одной функции передается как вход в следующую.const pipe = (...functions) => (input) =>
functions.reduce((acc, fn) => fn(acc), input);
// Пример функций
const multiplyByTwo = (num) => num * 2;
const addThree = (num) => num + 3;
const square = (num) => num ** 2;
// Использование pipe
const processNumber = pipe(multiplyByTwo, addThree, square);
console.log(processNumber(5)); // ((5 * 2) + 3) ** 2 = 121
В контексте RxJS
pipe
используется для работы с потоками данных, где через него можно передавать операторы, такие как map
, filter
, mergeMap
и другие.import { of } from 'rxjs';
import { map, filter } from 'rxjs/operators';
// Создаем поток данных
const numbers$ = of(1, 2, 3, 4, 5);
// Используем pipe для применения операторов
numbers$
.pipe(
filter((num) => num % 2 === 0), // Оставляем только четные
map((num) => num * 10) // Умножаем их на 10
)
.subscribe((result) => console.log(result));
// Вывод: 20, 40
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍16
Promise.all используется для параллельного выполнения нескольких промисов. Это полезно, когда нужно дождаться выполнения всех операций одновременно, например, загрузки данных с разных API.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍20🔥5
Чтобы изменить направление оси flexbox-контейнера, нужно использовать свойство CSS
flex-direction
. Это свойство определяет основную ось контейнера и направление размещения flex-элементов. Основная ось — горизонтальная, элементы располагаются слева направо. Это значение по умолчанию.
Основная ось — горизонтальная, элементы располагаются справа налево.
Основная ось — вертикальная, элементы располагаются сверху вниз.
Основная ось — вертикальная, элементы располагаются снизу вверх.
Горизонтальное направление (слева направо):
.container {
display: flex;
flex-direction: row; /* или просто не указывать, так как это значение по умолчанию */
}
Горизонтальное направление (справа налево):
.container {
display: flex;
flex-direction: row-reverse;
}
Вертикальное направление (сверху вниз):
.container {
display: flex;
flex-direction: column;
}
Вертикальное направление (снизу вверх):
.container {
display: flex;
flex-direction: column-reverse;
}
Пример HTML и CSS:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Flexbox Direction</title>
<style>
.container {
display: flex;
flex-direction: row; /* Измените значение на row-reverse, column, или column-reverse для проверки разных направлений */
border: 1px solid #000;
height: 200px;
}
.item {
flex: 1;
border: 1px solid #ccc;
padding: 10px;
margin: 5px;
text-align: center;
}
</style>
</head>
<body>
<div class="container">
<div class="item">Item 1</div>
<div class="item">Item 2</div>
<div class="item">Item 3</div>
</div>
</body>
</html>
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13❤3
- Inline-стили имеют самый высокий приоритет.
- ID-селекторы сильнее классов, а классы сильнее тегов.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍25🔥1
Чтобы повернуть блок на 45 градусов, используется свойство CSS
transform
с функцией rotate
. Это свойство позволяет применять различные трансформации к элементам, включая вращение, масштабирование, смещение и наклон..rotated-box {
width: 100px;
height: 100px;
background-color: lightblue;
transform: rotate(45deg);
}
Основной синтаксис
transform: rotate(угол);
Угол поворота элемента. В данном случае элемент поворачивается на 45 градусов по часовой стрелке.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
.rotated-box {
width: 100px;
height: 100px;
background-color: lightblue;
transform: rotate(45deg);
}
</style>
</head>
<body>
<div class="rotated-box"></div>
</body>
</html>
Позволяет применять различные визуальные эффекты к элементу, такие как вращение, масштабирование и смещение.
rotate
Используется для вращения элемента на заданный угол. Положительные значения поворачивают элемент по часовой стрелке, отрицательные — против часовой стрелки.Вращение элементов может использоваться для создания интересных визуальных эффектов, таких как поворот иконок, изображений или блоков текста.
В комбинации с анимацией (
@keyframes
и transition
), вращение может создавать динамичные и интерактивные пользовательские интерфейсы.Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13🔥2❤1
Преобразование типов может быть:
- Явным — например, использование функций String(), Number() для приведения типов.
- Неявным — когда JavaScript автоматически приводит один тип к другому в контексте операций (например, сложение строки и числа).
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍26
Свойство
box-sizing
в CSS управляет тем, как рассчитываются размеры элемента, включая ширину и высоту. Оно определяет, включаются ли в эти размеры внутренние отступы (padding
) и границы (border
), или же они добавляются отдельно. Размеры элемента считаются только по `width` и `height`, без учета
padding
и border
. Если добавить padding
или border
, фактические размеры элемента увеличатся. .box {
width: 200px;
height: 100px;
padding: 20px;
border: 10px solid black;
box-sizing: content-box;
}
width
и height
включают padding
и border
. Внутреннее содержимое (content
) будет автоматически уменьшаться, чтобы уложиться в заданные размеры. .box {
width: 200px;
height: 100px;
padding: 20px;
border: 10px solid black;
box-sizing: border-box;
}
Наследует значение
box-sizing
от родительского элемента. .parent {
box-sizing: border-box;
}
.child {
box-sizing: inherit; /* Унаследует border-box */
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍15❤6
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍32🔥4❤1
Это структура данных, которая представляет собой упорядоченный список элементов. В JavaScript массивы могут содержать любые типы данных: числа, строки, объекты, другие массивы и даже функции.
Массивы помогают удобно хранить и обрабатывать наборы данных. Вместо того чтобы создавать множество переменных, можно использовать массив, чтобы хранить сразу несколько значений и работать с ними с помощью специальных методов.
Массивы позволяют:
Хранить несколько значений в одной переменной
Перебирать элементы с помощью циклов
Добавлять, удалять, изменять элементы
Выполнять операции, например, сортировку и фильтрацию
В JavaScript массив можно создать разными способами:
С использованием литерала массива
let fruits = ["яблоко", "банан", "апельсин"];
С использованием конструктора
Array
let numbers = new Array(1, 2, 3, 4, 5);
Доступ к элементу массива осуществляется по индексу (начинается с 0):
let fruits = ["яблоко", "банан", "апельсин"];
console.log(fruits[0]); // "яблоко"
console.log(fruits[1]); // "банан"
Добавление элемента в конец
push()
let arr = [1, 2, 3];
arr.push(4);
console.log(arr); // [1, 2, 3, 4]
Удаление последнего элемента
pop()
arr.pop();
console.log(arr); // [1, 2, 3]
Добавление элемента в начало
unshift()
arr.unshift(0);
console.log(arr); // [0, 1, 2, 3]
Удаление первого элемента
shift()
arr.shift();
console.log(arr); // [1, 2, 3]
Перебор массива
forEach()
arr.forEach(item => console.log(item));
Фильтрация элементов
filter()
let evenNumbers = arr.filter(num => num % 2 === 0);
console.log(evenNumbers); // [2]
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍23
1. GET:
- Используется для получения данных с сервера.
- Данные передаются в URL (в строке запроса), ограничены по длине.
- Менее безопасен, так как параметры видны в URL.
2. POST:
- Используется для отправки данных на сервер.
- Данные передаются в теле запроса, не отображаются в URL.
- Подходит для передачи больших объемов информации и конфиденциальных данных.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍33🔥9🤯2❤1
Выбор между объектно-ориентированным программированием (ООП) и функциональным программированием (ФП) зависит от задачи, которую нужно решить. Оба подхода имеют свои плюсы и минусы.
Объектно-ориентированное программирование подходит, когда:
Нужно моделировать реальные объекты и их поведение
Приложение состоит из множества взаимодействующих сущностей
Важно инкапсулировать данные и защитить их от прямого изменения
Требуется повторное использование кода через наследование и полиморфизм
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(`${this.name} издает звук`);
}
}
class Dog extends Animal {
speak() {
console.log(`${this.name} лает`);
}
}
const dog = new Dog("Бобик");
dog.speak(); // "Бобик лает"
Функциональный подход хорош, если
Код должен быть чистым и предсказуемым
Нужно избегать изменений состояния (иммутабельность)
Требуется много работы с массивами, коллекциями данных
Нужно легко писать асинхронный код
const double = num => num * 2;
const numbers = [1, 2, 3, 4];
const doubledNumbers = numbers.map(double);
console.log(doubledNumbers); // [2, 4, 6, 8]
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍22
1. Родительский компонент — дочерний компонент:
- Передача через props или события.
2. Общий контекст или хранилище:
- Использование глобального состояния (Redux, Zustand, Context API).
3. Взаимодействие через сервисы:
- Например, через API или WebSocket.
4. Pub-Sub модель:
- С помощью событий или библиотек типа EventEmitter.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥11👍10❤4
Глобальное состояние – это данные, которые должны быть доступны в разных частях приложения. Чтобы определить, является ли состояние глобальным, нужно задать себе несколько вопросов:
Если одно и то же состояние необходимо сразу нескольким компонентам, расположенным в разных частях дерева компонентов, скорее всего, его стоит сделать глобальным. В React, если в разных компонентах нужна информация о текущем пользователе (
user
), лучше хранить её в глобальном состоянии (например, в Context или Redux). // Глобальное состояние (например, Context API)
const UserContext = createContext();
function App() {
const [user, setUser] = useState({ name: "Иван", isLoggedIn: true });
return (
<UserContext.Provider value={user}>
<Navbar />
<Profile />
</UserContext.Provider>
);
}
function Navbar() {
const user = useContext(UserContext);
return <div>Привет, {user.name}!</div>;
}
function Profile() {
const user = useContext(UserContext);
return <div>Профиль пользователя: {user.name}</div>;
}
Если данные должны оставаться неизменными при смене страниц, лучше использовать глобальное хранилище (например, Redux, Zustand или React Context). Корзина товаров в интернет-магазине
Авторизация пользователя
Темная/светлая тема приложения
Если данные теряются при смене страницы – это сигнал, что их нужно вынести в глобальное хранилище.
Если одно состояние обновляется в одном компоненте, но влияет на работу нескольких других компонентов, оно должно быть глобальным. В чате, если новое сообщение приходит в одном компоненте (
ChatInput
), а отображается в другом (ChatList
), логично хранить все сообщения в глобальном состоянии. const ChatContext = createContext();
function ChatProvider({ children }) {
const [messages, setMessages] = useState([]);
const sendMessage = (text) => {
setMessages([...messages, { text, id: Date.now() }]);
};
return (
<ChatContext.Provider value={{ messages, sendMessage }}>
{children}
</ChatContext.Provider>
);
}
function ChatList() {
const { messages } = useContext(ChatContext);
return messages.map((msg) => <p key={msg.id}>{msg.text}</p>);
}
function ChatInput() {
const { sendMessage } = useContext(ChatContext);
const [text, setText] = useState("");
return (
<input
value={text}
onChange={(e) => setText(e.target.value)}
onKeyPress={(e) => {
if (e.key === "Enter") {
sendMessage(text);
setText("");
}
}}
/>
);
}
Иногда состояние можно не делать глобальным, а просто хранить его в URL (в
query-параметрах
или path
). ID открытого товара:
/products/123
Фильтры товаров:
/shop?category=shoes&sort=price
Страница чата с пользователем:
/chat?user=ivan
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍12❤1
Swipe right or swipe left
Что делать, если твои мэтчи в жизни не такие точные, как твой код?
Спокойно, 14 февраля в 19:00 по МСК мы разберём, как ML анализирует speed dating и предсказывает match.
📌 Мы возьмем реальные данные со speed dating.
📌 Обучим модель, которая скажет: match или swipe left.
📌 Разберём, какие признаки реально важны (спойлер: работа в IT — не прям гарантия успеха (наши маркетологи подтверждают 😥).
💡 Приходи, если хочешь прокачать свой Python, ML и, возможно, станешь идеальной парой, как самый стильные форсы.
👉 Записаться
Что делать, если твои мэтчи в жизни не такие точные, как твой код?
Спокойно, 14 февраля в 19:00 по МСК мы разберём, как ML анализирует speed dating и предсказывает match.
📌 Мы возьмем реальные данные со speed dating.
📌 Обучим модель, которая скажет: match или swipe left.
📌 Разберём, какие признаки реально важны (спойлер: работа в IT — не прям гарантия успеха (наши маркетологи подтверждают 😥).
💡 Приходи, если хочешь прокачать свой Python, ML и, возможно, станешь идеальной парой, как самый стильные форсы.
👉 Записаться
❤1
Это механизм JavaScript, при котором объявления переменных и функций поднимаются в начало своей области видимости. Например:
- Переменные, объявленные с var, поднимаются, но их значение остается undefined.
- let и const поднимаются, но не инициализируются.
- Функции полностью доступны до их объявления.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍17🤯4💊2❤1
Redux – мощный инструмент, но не всегда он необходим. Существует множество альтернатив, каждая из которых подходит для разных сценариев.
Подходит для небольших и средних приложений
Встроено в React (не требует установки дополнительных библиотек)
useContext` позволяет передавать данные по дереву компонентов без "прокидывания" через
props
useReducer
работает как Redux
, но проще const AuthContext = createContext();
function authReducer(state, action) {
switch (action.type) {
case "LOGIN":
return { ...state, isAuthenticated: true, user: action.payload };
case "LOGOUT":
return { ...state, isAuthenticated: false, user: null };
default:
return state;
}
}
function AuthProvider({ children }) {
const [state, dispatch] = useReducer(authReducer, {
isAuthenticated: false,
user: null,
});
return (
<AuthContext.Provider value={{ state, dispatch }}>
{children}
</AuthContext.Provider>
);
}
function LoginButton() {
const { dispatch } = useContext(AuthContext);
return (
<button onClick={() => dispatch({ type: "LOGIN", payload: "Иван" })}>
Войти
</button>
);
}
Проще Redux, но с теми же возможностями
Нет лишних
actions
и reducers
, только функции 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}</button>;
}
Идеален для React-приложений
Гибче, чем Redux, с концепцией "атомов" (раздельные состояния)
import { atom, useRecoilState } from "recoil";
const countState = atom({
key: "count",
default: 0,
});
function Counter() {
const [count, setCount] = useRecoilState(countState);
return <button onClick={() => setCount(count + 1)}>Счетчик: {count}</button>;
}
Напоминает Recoil, но без сложных концепций
Поддерживает React Suspense и асинхронные состояния
import { atom, useAtom } from "jotai";
const countAtom = atom(0);
function Counter() {
const [count, setCount] = useAtom(countAtom);
return <button onClick={() => setCount(count + 1)}>Счетчик: {count}</button>;
}
Автоматически отслеживает изменения состояния
Удобен для сложных приложений
import { makeAutoObservable } from "mobx";
import { observer } from "mobx-react-lite";
class CounterStore {
count = 0;
constructor() {
makeAutoObservable(this);
}
increment() {
this.count++;
}
}
const store = new CounterStore();
const Counter = observer(() => (
<button onClick={() => store.increment()}>Счетчик: {store.count}</button>
));
Подходит для сложных логик (например, UI-анимаций, состояний формы)
Удобно описывать последовательности действий
import { createMachine, interpret } from "xstate";
const toggleMachine = createMachine({
id: "toggle",
initial: "inactive",
states: {
inactive: { on: { TOGGLE: "active" } },
active: { on: { TOGGLE: "inactive" } },
},
});
const service = interpret(toggleMachine).start();
service.send("TOGGLE"); // Меняет состояние
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍22🔥5❤1
- Объединяет ветки, создавая новый коммит.
- Сохраняет историю изменений обеих веток.
2. Rebase:
- Переносит коммиты одной ветки поверх другой.
- История становится линейной, но теряются промежуточные изменения.
Разница: merge сохраняет все ветвления, а rebase упрощает историю.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
💊17👍13😁1