M3 | WebDev
103 subscribers
105 photos
4 videos
14 links
Your guide to the world of programming 🌐🚀
Download Telegram
Многие не задумываются, но даже так можно делать… 🐱💻

Вот вам пример на JavaScript:

const originalPush = Array.prototype.push;

Array.prototype.push = function (...args) {
console.log('Элементы добавлены:', args);
return originalPush.apply(this, args);
};

const arr = [1, 2, 3];

arr.push(4, 5); // Выведет: Элементы добавлены: [4, 5]


🔥 Что происходит? Мы сохраняем оригинальный метод push, переопределяем его, чтобы добавить console.log, а затем вызываем оригинальный метод через apply.

⚡️ Это может быть полезно для отладки или отслеживания изменений массивов в вашем приложении. Но аккуратнее: изменение встроенных методов может привести к неожиданным багам в других местах вашего кода.
Архитектура — это фундамент любого программного проекта. Она определяет, как система будет развиваться, масштабироваться и поддерживаться. Ошибки на этом этапе могут привести к хаосу, увеличенным срокам и непредсказуемости. Именно поэтому архитектура — это самое главное в программировании.

Существует множество подходов к проектированию архитектуры:

• Микросервисная архитектура
• Монолитная архитектура
• Чистая архитектура (Clean Architecture)
• Feature-Sliced Design
• И многие другие.

Каждая из них подходит для разных задач, но лично я выбираю доменно-ориентированную архитектуру (Domain-Oriented Architecture, DOA).

🔑 Почему я выбираю DOA?

1. Четкие границы контекста (Bounded Context):
Система делится на независимые домены с четко определенными правилами, что предотвращает «эффект домино».

2. Фокус на бизнес-логике:
Архитектура строится вокруг потребностей бизнеса, а не технологий. Это позволяет создавать решения, которые действительно решают задачи заказчика.

3. Модульность и масштабируемость:
Каждый домен автономен, что упрощает тестирование, поддержку и развитие проекта.

4. Единый язык (Ubiquitous Language):
Использование общего языка между бизнесом и разработчиками помогает избежать недопонимания.

💡 Почему архитектура важна:

• Она задает основу для всей системы.
• Облегчает внедрение новых разработчиков в проект.
• Упрощает масштабирование и добавление новых функций.
• Делает систему предсказуемой и понятной.

Для меня DOA — это подход, который позволяет создавать системы, развивающиеся вместе с бизнесом. Такие системы не только устойчивы к изменениям, но и обладают важным преимуществом: итоговый продукт становится доступным и понятным для разработчиков любого уровня подготовки.
Про всплытие (или event bubbling) в JavaScript 🌊

Всплытие событий — это основополагающий механизм в браузерном JavaScript.

🔧 Как это работает?

1. При нажатии на элемент событие сначала срабатывает на нём (фаза захвата).

2. Затем оно поднимается кроме других объектов (фаза всплытия).

🎓 Пример:
<div id="parent">
<button id="child">Кликни меня!</button>
</div>

document.getElementById('parent').addEventListener('click', () => {
console.log('Клик на parent!');
});

document.getElementById('child').addEventListener('click', () => {
console.log('Клик на child!');
});


🔎 Что получим при клике на child?

1. Сначала выполнится console.log('Клик на child!');

2. Затем сработает console.log('Клик на parent!');

Вот и всплытие 👇

🏢 Когда это не нужно?
Иногда нам нужно остановить пропагацию события.

document.getElementById('child').addEventListener('click', (event) => {
event.stopPropagation(); // Прекращает всплытие
console.log('Теперь только child!');
});

Этот приём часто используют в сложных взаимодействиях.

Если остались вопросы про всплытие и погружение, пишите в комментарии! 🙋‍♂️
💡 preventDefault — как это работает?

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

👉 Метод event.preventDefault() останавливает стандартное действие браузера. Это полезно, если вы хотите реализовать свою логику при каком-либо событии.

Пример:
document.querySelector('a').addEventListener('click', (event) => {
event.preventDefault();
console.log('Клик перехвачен, но перехода не будет!');
});


🔥 Используйте preventDefault, чтобы:

• Сделать кастомную отправку формы через AJAX 📨
• Остановить переходы по ссылкам 📌
• Управлять кликами, свайпами и любыми действиями пользователя 🎮

Но не путайте с stopPropagation()! Этот метод блокирует всплытие событий, а preventDefault — только стандартное поведение.
Контекст провайдер в React: Что это и как его правильно использовать

Контекст провайдер (Context Provider) в React — это мощный инструмент для передачи данных через дерево компонентов, избегая необходимости явно передавать пропсы на каждом уровне. Это особенно полезно, когда данные, такие как тема, авторизация пользователя или настройки приложения, должны быть доступны во многих компонентах.

Что такое контекст в React?
Контекст позволяет создавать глобальные переменные для React-приложения. Он состоит из двух основных частей:

1. Контекст — создаётся с помощью React.createContext и служит хранилищем значений.
2. Провайдер (Provider) — оборачивает компоненты, которым необходимо передать значения.

Пример использования контекста
1. Создание контекста
import React, { createContext, useState } from 'react';

// Создаём контекст
export const ThemeContext = createContext();

export const ThemeProvider = ({ children }) => {
const [theme, setTheme] = useState('light');

const toggleTheme = () => {
setTheme((prevTheme) => (prevTheme === 'light' ? 'dark' : 'light'));
};

return (
<ThemeContext.Provider value={{ theme, toggleTheme }}>
{children}
</ThemeContext.Provider>
);
};


2. Использование провайдера
Провайдер оборачивает компоненты, которые должны получать данные из контекста.
import React from 'react';
import { ThemeProvider } from './ThemeContext';
import App from './App';

const Root = () => (
<ThemeProvider>
<App />
</ThemeProvider>
);

export default Root;


3. Потребление контекста в дочерних компонентах
В дочерних компонентах доступ к данным осуществляется через useContext.
import React, { useContext } from 'react';
import { ThemeContext } from './ThemeContext';

const ThemeSwitcher = () => {
const { theme, toggleTheme } = useContext(ThemeContext);

return (
<div>
<p>Текущая тема: {theme}</p>
<button onClick={toggleTheme}>Сменить тему</button>
</div>
);
};

export default ThemeSwitcher;


Контекст провайдер в React — это мощный инструмент для управления состоянием на уровне приложения. Правильное использование контекста упрощает структуру кода и делает приложение более поддерживаемым. Однако всегда помните, что контекст — это не замена сложных менеджеров состояния, и его следует использовать с умом.
Как избежать ада ререндеров с контекстом в React?
Контекст в React передаёт значения всем дочерним компонентам, и любое изменение значения контекста вызывает ререндер всех потребителей (consumer). Это может существенно повлиять на производительность приложения, особенно если дерево компонентов большое.

Вот несколько стратегий, чтобы избежать "ада ререндеров":

1. Разделяйте контексты для разных данных
Если вы используете один контекст для хранения нескольких типов данных (например, тема, авторизация и настройки), то изменение любой из этих данных вызовет ререндер всех потребителей. Лучше создать отдельный контекст для каждой группы данных.

Пример:
// Тема
export const ThemeContext = createContext();

// Авторизация
export const AuthContext = createContext();

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

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

Плохо:
const UserContext = createContext({
user: { id: 1, name: 'Михаил', email: 'example@mail.com' },
updateUser: () => {},
});


Лучше:
const UserContext = createContext();
const UpdateUserContext = createContext();

Теперь компоненты, которым нужно только имя пользователя, не будут ререндериться при изменении функции updateUser.

3. Используйте мемоизацию контекстных значений
Если значение контекста вычисляется динамически, каждый ререндер провайдера будет пересоздавать объект или функцию, даже если данные не изменились. Это приводит к ререндерам потребителей.

Решение — использовать useMemo для мемоизации значения.

Пример:
import React, { createContext, useState, useMemo } from 'react';

export const ThemeContext = createContext();

export const ThemeProvider = ({ children }) => {
const [theme, setTheme] = useState('light');

const value = useMemo(() => ({ theme, toggleTheme: () => setTheme((t) => (t === 'light' ? 'dark' : 'light')) }), [theme]);

return <ThemeContext.Provider value={value}>{children}</ThemeContext.Provider>;
};

Теперь значение контекста обновляется только при изменении theme.

4. Потребляйте контекст там, где это необходимо
Избегайте использования useContext в компонентах, где данные контекста не нужны. Чем меньше компонентов напрямую потребляют контекст, тем меньше ререндеров.

Плохо:
const Parent = () => {
const { theme } = useContext(ThemeContext); // Используется только в дочернем компоненте
return <Child />;
};


Лучше:
const Parent = () => <Child />;

const Child = () => {
const { theme } = useContext(ThemeContext);
return <p>Тема: {theme}</p>;
};


5. Используйте селекторы контекста
Селекторы позволяют подписываться только на определённые части данных контекста. Для этого можно использовать кастомные хуки или библиотеки, такие как reselect-context.

Пример кастомного хука:
export const useTheme = () => {
const context = useContext(ThemeContext);
if (!context) throw new Error('useTheme must be used within a ThemeProvider');
return context.theme;
};

export const useToggleTheme = () => {
const context = useContext(ThemeContext);
if (!context) throw new Error('useToggleTheme must be used within a ThemeProvider');
return context.toggleTheme;
};

Теперь можно подписываться только на theme или toggleTheme, а не на оба одновременно.

6. Используйте компонент React.memo
Если компонент использует контекст, но не должен ререндериться при его обновлении, можно обернуть его в React.memo.

Пример:
const ThemedComponent = React.memo(() => {
const { theme } = useContext(ThemeContext);
return <div>Текущая тема: {theme}</div>;
});


7. Подключение контекста через компонент-посредник
Если компоненту нужно только обновлять данные контекста, используйте специальный компонент, который изолирует изменения.
Пример:
const ThemeUpdater = () => {
const { toggleTheme } = useContext(ThemeContext);
return <button onClick={toggleTheme}>Сменить тему</button>;
};

Таким образом, ререндер затронет только ThemeUpdater, а не всю структуру.

Заключение
Чтобы избежать "ада ререндеров" при использовании контекста в React:

1. Разделяйте данные на несколько контекстов.
2. Используйте useMemo для мемоизации значений.
3. Подключайте контекст только в необходимых местах.
4. Используйте кастомные хуки и мемоизацию для работы с контекстом.

Применяя эти подходы, вы сможете эффективно управлять состоянием приложения и обеспечить высокую производительность.
🔍 Интересный JavaScript-кейс:
const obj = {
"1": "a",
1: "6",
[1]: "B"
};

console.log(obj["1"]);
💡 Что выведет этот код в консоль?
Anonymous Quiz
50%
a
14%
6
36%
B
💡 CSS-переменные — что это и зачем они нужны?

CSS-переменные (или custom properties) — это мощный инструмент, который позволяет задавать повторно используемые значения прямо в CSS. Они работают как переменные в JavaScript, но предназначены для стилей. 🎨

📌 Как задать CSS-переменную?
:root {
--main-color: #3498db;
--padding-size: 16px;
}


Переменные определяются в специальном синтаксисе --имя-переменной и обычно задаются в :root, чтобы они применялись глобально.

📌 Как использовать?
button {
background-color: var(--main-color);
padding: var(--padding-size);
}


С помощью функции var() можно подключать переменные в любых свойствах.

📌 Зачем это нужно?

1. 📋 Удобство: Меняете переменную — и обновляете дизайн сразу во всех местах.
2. 🎯 Темизация: Легко переключать темы (светлая/тёмная, брендовые цвета).
3. 🛠 Гибкость: Позволяют динамически изменять стили через JavaScript:
document.documentElement.style.setProperty('--main-color', '#e74c3c');


📌 Поддержка
CSS-переменные поддерживаются всеми современными браузерами (кроме IE 😅). Так что смело используйте!
🔥 Emits в Vue: Как правильно передавать события 🔥

Если вы работаете с компонентами Vue, вы наверняка сталкивались с ситуацией, когда нужно передать событие из дочернего компонента в родительский. Для этого используются emits.

Что такое emits?
emits — это способ декларации событий, которые компонент может отправлять. Это делает ваш код более предсказуемым, типизированным и удобным для отладки.

Пример использования:
Дочерний компонент:
<script setup>
import { defineEmits } from 'vue';

// Декларируем событие "submit"
const emit = defineEmits(['submit']);

function handleSubmit() {
emit('submit', { message: 'Данные отправлены!' });
}
</script>

<template>
<button @click="handleSubmit">Отправить</button>
</template>


Родительский компонент:
<script setup>
function onSubmit(payload) {
console.log(payload.message); // Данные отправлены!
}
</script>

<template>
<ChildComponent @submit="onSubmit" />
</template>


Почему это важно?
1️⃣ Ясность и предсказуемость: Выявление всех событий в одном месте (через defineEmits) упрощает понимание кода. Вы всегда знаете, какие события ожидаются.

2️⃣ Типизация событий: Если вы используете TypeScript, можно типизировать события:
<script setup lang="ts">
const emit = defineEmits<{
(event: 'submit', payload: { message: string }): void;
}>();
</script>


3️⃣ Снижение ошибок: Если вы попробуете отправить событие, не описанное в defineEmits, Vue выведет предупреждение в консоль.

📌 Совет: Используйте defineEmits вместе с defineProps, чтобы максимально упростить связь между компонентами.
Валидация на фронте
🚀 Скоро запуск аналитического крипто-проекта!

Готовлю платформу, которая поможет трейдерам получать актуальную информацию о рынке. В группу буду выкладывать детали разработки — проектирование и разработка сайта, ботов для Telegram, а также клиентской и серверной инфраструктуры. Всё это также можно будет смотреть в реальном времени на стримах в Twitch.

Подписывайтесь, чтобы следить за процессом: 👉 www.twitch.tv/m34r7
M3 | WebDev pinned a photo