Frontend | Вопросы собесов
Сайт: https://easyoffer.ru/ Все каналы: t.me/+xGeAw6ckJ4liYzQy Контакт для рекламы: @sendme_ads
إظهار المزيد📈 نظرة تحليلية على قناة تيليجرام Frontend | Вопросы собесов
تُعد قناة Frontend | Вопросы собесов (@easy_javascript_ru) في القطاع اللغوي الروسية لاعباً نشطاً. يضم المجتمع حالياً 17 326 مشتركاً، محتلاً المرتبة 7 465 في فئة التكنولوجيات والتطبيقات والمرتبة 37 811 في منطقة روسيا.
📊 مؤشرات الجمهور والحراك
منذ تأسيسه في невідомо، حقق المشروع نمواً سريعاً وجمع 17 326 مشتركاً.
بحسب آخر البيانات بتاريخ 05 نوفمبر, 2026، تحافظ القناة على نشاط مستقر. خلال آخر 30 يوماً تغيّر عدد الأعضاء بمقدار -286، وفي آخر 24 ساعة بمقدار -4، مع بقاء الوصول العام مرتفعاً.
- حالة التحقق: غير موثّقة
- معدل التفاعل (ER): يبلغ متوسط تفاعل الجمهور 6.64%. وخلال أول 24 ساعة من النشر يحصد المحتوى عادةً 4.45% من ردود الفعل نسبةً إلى إجمالي المشتركين.
- وصول المنشورات: يحصل كل منشور على متوسط 1 152 مشاهدة. وخلال اليوم الأول يجمع عادةً 771 مشاهدة.
- التفاعلات والاستجابة: يتفاعل الجمهور بانتظام؛ متوسط التفاعلات لكل منشور يبلغ 4.
- الاهتمامات الموضوعية: يركز المحتوى على مواضيع رئيسية مثل ставь, браузер, html, border, flex.
📝 الوصف وسياسة المحتوى
يصف المؤلف القناة بأنها مساحة للتعبير عن الآراء الذاتية:
“Сайт: https://easyoffer.ru/
Все каналы: t.me/+xGeAw6ckJ4liYzQy
Контакт для рекламы: @sendme_ads”
بفضل وتيرة التحديث المرتفعة (أحدث البيانات بتاريخ 06 نوفمبر, 2026) تحافظ القناة على حداثتها ومستوى وصول مرتفع. وتُظهر التحليلات تفاعلاً نشطاً من الجمهور، ما يجعلها نقطة تأثير مهمة ضمن فئة التكنولوجيات والتطبيقات.
[].
let propName = 'name';
let person = {
[propName]: 'Alice'
};
console.log(person.name); // 'Alice'
🚩Использование вычисляемых свойств
1⃣Динамическое имя свойства на основе переменной
let key = 'age';
let person = {
name: 'Alice',
[key]: 25
};
console.log(person.name); // 'Alice'
console.log(person.age); // 25
2⃣Использование выражений в качестве имен свойств
let i = 0;
let obj = {
['prop_' + ++i]: i,
['prop_' + ++i]: i,
['prop_' + ++i]: i
};
console.log(obj); // { prop_1: 1, prop_2: 2, prop_3: 3 }
3⃣Вложенные вычисляемые свойства
let prefix = 'user';
let index = 1;
let users = {
[prefix + index]: { name: 'Alice' },
[prefix + (index + 1)]: { name: 'Bob' }
};
console.log(users.user1.name); // 'Alice'
console.log(users.user2.name); // 'Bob'
4⃣Использование функции для вычисления имен свойств
function createKey(base, index) {
return base + index;
}
let obj = {
[createKey('key', 1)]: 'value1',
[createKey('key', 2)]: 'value2'
};
console.log(obj.key1); // 'value1'
console.log(obj.key2); // 'value2'
🚩Применение в реальных сценариях
🟠Создание объекта с динамическими ключами
Предположим, вам нужно создать объект для хранения оценок студентов, где ключи представляют собой имена студентов, а значения — их оценки.
let studentName1 = 'Alice';
let studentName2 = 'Bob';
let grades = {
[studentName1]: 85,
[studentName2]: 92
};
console.log(grades.Alice); // 85
console.log(grades.Bob); // 92
🟠Использование вычисляемых свойств для формирования запросов
Допустим, у вас есть объект, представляющий параметры фильтра для поиска, и вы хотите динамически создавать ключи на основе выбранных фильтров.
function getFilterKey(filterName) {
return `filter_${filterName}`;
}
let filters = {};
filters[getFilterKey('age')] = 25;
filters[getFilterKey('location')] = 'New York';
console.log(filters); // { filter_age: 25, filter_location: 'New York' }
Ставь 👍 и забирай 📚 Базу знанийtype, указывающее тип экшна. Дополнительно могут быть добавлены другие свойства для передачи данных.
const incrementAction = {
type: 'INCREMENT'
};
const addTodoAction = {
type: 'ADD_TODO',
payload: {
id: 1,
text: 'Learn Redux'
}
};
🚩Создатели экшнов (Action Creators)
Это функции, которые создают экшны. Это полезно для создания экшнов динамически и обеспечения единообразия.
const increment = () => {
return {
type: 'INCREMENT'
};
};
const addTodo = (id, text) => {
return {
type: 'ADD_TODO',
payload: {
id,
text
}
};
};
🚩Изменение состояния с помощью редьюсера
Чтобы изменить состояние в Redux, используется редьюсер. Редьюсер — это функция, которая принимает текущее состояние и экшн, а затем возвращает новое состояние.
const initialState = {
count: 0,
todos: []
};
const rootReducer = (state = initialState, action) => {
switch (action.type) {
case 'INCREMENT':
return {
...state,
count: state.count + 1
};
case 'ADD_TODO':
return {
...state,
todos: [...state.todos, action.payload]
};
default:
return state;
}
};
🚩Пример использования Redux в React
1⃣Установка Redux
Сначала установим необходимые пакеты
npm install redux react-redux
2⃣Создание хранилища (store)
import { createStore } from 'redux';
import rootReducer from './reducers';
const store = createStore(rootReducer);
3⃣Подключение React к Redux
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import App from './App';
import store from './store';
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
);
🚩Объяснение
1⃣Создание экшнов
const incrementAction = { type: 'INCREMENT' };
const addTodoAction = {
type: 'ADD_TODO',
payload: { id: 1, text: 'Learn Redux' }
};
2⃣Создатели экшнов
const increment = () => ({ type: 'INCREMENT' });
const addTodo = (id, text) => ({
type: 'ADD_TODO',
payload: { id, text }
});
3⃣Редьюсер
const rootReducer = (state = initialState, action) => {
switch (action.type) {
case 'INCREMENT':
return { ...state, count: state.count + 1 };
case 'ADD_TODO':
return { ...state, todos: [...state.todos, action.payload] };
default:
return state;
}
};
Ставь 👍 и забирай 📚 Базу знанийstate)
Действие (action)
2⃣Возвращает новое состояние.
const reducer = (state, action) => {
switch (action.type) {
case 'ACTION_TYPE':
// Возвращаем новое состояние
return {
...state,
// Обновляем определенные свойства
};
default:
return state;
}
};
🚩Пример использования редьюсера
Инициализация состояния
const initialState = {
count: 0
};
Определение редьюсера
const counterReducer = (state = initialState, action) => {
switch (action.type) {
case 'INCREMENT':
return {
...state,
count: state.count + 1
};
case 'DECREMENT':
return {
...state,
count: state.count - 1
};
default:
return state;
}
};
🚩Использование редьюсера с useReducer в React
React предоставляет хук useReducer для управления состоянием с помощью редьюсера в функциональных компонентах.
import React, { useReducer } from 'react';
const initialState = { count: 0 };
const counterReducer = (state, action) => {
switch (action.type) {
case 'INCREMENT':
return { count: state.count + 1 };
case 'DECREMENT':
return { count: state.count - 1 };
default:
return state;
}
};
const Counter = () => {
const [state, dispatch] = useReducer(counterReducer, initialState);
return (
<div>
<p>Count: {state.count}</p>
<button onClick={() => dispatch({ type: 'INCREMENT' })}>Increment</button>
<button onClick={() => dispatch({ type: 'DECREMENT' })}>Decrement</button>
</div>
);
};
export default Counter;
Ставь 👍 и забирай 📚 Базу знанийuseEffect. Когда компонент демонтируется, React вызывает функцию очистки, которую можно определить внутри useEffect.
🤔 Использование `useEffect` для отслеживания демонтирования
Хук useEffect позволяет выполнять побочные эффекты в функциональных компонентах. Функция очистки, возвращаемая из useEffect, выполняется при демонтировании компонента.
🤔 Пример использования
import React, { useEffect } from 'react';
const MyComponent = () => {
useEffect(() => {
console.log('Component mounted');
// Функция очистки вызывается при демонтировании компонента
return () => {
console.log('Component will unmount');
};
}, []); // Пустой массив зависимостей означает, что эффект выполнится только при монтировании и демонтировании
return (
<div>
<p>My Component</p>
</div>
);
};
export default MyComponent;
🤔 Объяснение
1️⃣ Хук `useEffect`:
useEffect(() => {
console.log('Component mounted');
return () => {
console.log('Component will unmount');
};
}, []);
- Первый аргумент: Функция, которая выполняется после рендеринга компонента. Если эта функция возвращает другую функцию, она будет вызвана при демонтировании компонента.
- Второй аргумент: Массив зависимостей. Если массив пуст, эффект будет выполнен только при монтировании и демонтировании компонента.
🤔 Пример с реальным использованием
Рассмотрим пример, где мы используем WebSocket и хотим закрыть соединение при демонтировании компонента.
import React, { useEffect, useState } from 'react';
const WebSocketComponent = () => {
const [messages, setMessages] = useState([]);
useEffect(() => {
const socket = new WebSocket('ws://example.com/socket');
socket.onmessage = (event) => {
setMessages((prevMessages) => [...prevMessages, event.data]);
};
console.log('WebSocket connection opened');
return () => {
socket.close();
console.log('WebSocket connection closed');
};
}, []);
return (
<div>
<h1>WebSocket Messages</h1>
<ul>
{messages.map((message, index) => (
<li key={index}>{message}</li>
))}
</ul>
</div>
);
};
export default WebSocketComponent;
🤔 Объяснение
1️⃣ Открытие WebSocket соединения:
const socket = new WebSocket('ws://example.com/socket');
Соединение открывается при монтировании компонента.
2️⃣ Обработка входящих сообщений:
socket.onmessage = (event) => {
setMessages((prevMessages) => [...prevMessages, event.data]);
};
Входящие сообщения добавляются в состояние компонента.
3️⃣ Закрытие WebSocket соединения при демонтировании:
return () => {
socket.close();
console.log('WebSocket connection closed');
};
Соединение закрывается при демонтировании компонента, что предотвращает утечки памяти и другие потенциальные проблемы.
🤔 Итог
Для отслеживания демонтирования функционального компонента в React используйте функцию очистки внутри хука useEffect. Это полезно для выполнения операций очистки, таких как закрытие соединений, отмена подписок или освобождение ресурсов.
Короче говоря: Используйте хук useEffect с функцией очистки, чтобы отслеживать демонтирование функционального компонента и выполнять необходимые операции очистки.
🔥 ТОП ВОПРОСОВ С СОБЕСОВ
🔒 База собесов | 🔒 База тестовыхuseState позволяет добавить состояние в функциональный компонент.
import React, { useState } from 'react';
const Counter = () => {
const [count, setCount] = useState(0);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
};
export default Counter;
🟠useContext
useContext позволяет использовать контекст для передачи данных через дерево компонентов без необходимости передавать пропсы на промежуточных уровнях.
import React, { useContext } from 'react';
const ThemeContext = React.createContext('light');
const ThemedComponent = () => {
const theme = useContext(ThemeContext);
return <div style={{ background: theme === 'light' ? '#fff' : '#333', color: theme === 'light' ? '#000' : '#fff' }}>
The current theme is {theme}
</div>;
};
const App = () => {
return (
<ThemeContext.Provider value="dark">
<ThemedComponent />
</ThemeContext.Provider>
);
};
export default App;
🟠useReducer
useReducer — это альтернатива useState для управления более сложным состоянием в компоненте.
import React, { useReducer } from 'react';
const initialState = { count: 0 };
function reducer(state, action) {
switch (action.type) {
case 'increment':
return { count: state.count + 1 };
case 'decrement':
return { count: state.count - 1 };
default:
throw new Error();
}
}
const Counter = () => {
const [state, dispatch] = useReducer(reducer, initialState);
return (
<div>
<p>Count: {state.count}</p>
<button onClick={() => dispatch({ type: 'increment' })}>Increment</button>
<button onClick={() => dispatch({ type: 'decrement' })}>Decrement</button>
</div>
);
};
export default Counter;
🟠useRef
useRef возвращает изменяемый объект-реф, который сохраняется при повторных рендерах компонента. Это часто используется для доступа к DOM-элементам или для сохранения переменных, которые не вызывают повторный рендер при изменении.
import React, { useRef } from 'react';
const TextInputWithFocusButton = () => {
const inputEl = useRef(null);
const onButtonClick = () => {
// "current" указывает на смонтированный элемент input
inputEl.current.focus();
};
return (
<div>
<input ref={inputEl} type="text" />
<button onClick={onButtonClick}>Focus the input</button>
</div>
);
};
export default TextInputWithFocusButton;
Ставь 👍 и забирай 📚 Базу знанийimport React, { useState } from 'react';
const ControlledComponent = () => {
const [inputValue, setInputValue] = useState('');
const handleChange = (event) => {
setInputValue(event.target.value);
};
return (
<div>
<label>
Name:
<input type="text" value={inputValue} onChange={handleChange} />
</label>
<p>Current value: {inputValue}</p>
</div>
);
};
export default ControlledComponent;
🚩Особенности контролируемых компонентов
🟠Состояние в React
Значение элемента формы хранится в состоянии компонента.
🟠Обработка событий
Все изменения отслеживаются через события (например, onChange) и обновляют состояние компонента.
🟠Односторонний поток данных
Данные идут от состояния компонента к элементу формы, обеспечивая контроль над значением.
🚩Неконтролируемые компоненты
Неконтролируемый компонент управляет своим состоянием через DOM. Значение элемента формы извлекается непосредственно из DOM, а не из состояния компонента.
import React, { useRef } from 'react';
const UncontrolledComponent = () => {
const inputRef = useRef(null);
const handleSubmit = (event) => {
event.preventDefault();
alert('Submitted value: ' + inputRef.current.value);
};
return (
<form onSubmit={handleSubmit}>
<label>
Name:
<input type="text" ref={inputRef} />
</label>
<button type="submit">Submit</button>
</form>
);
};
export default UncontrolledComponent;
🚩Особенности неконтролируемых компонентов
🟠Состояние в DOM
Значение элемента формы хранится в самом DOM-элементе.
🟠Использование рефов
Для доступа к значению элемента используется реф (например, через useRef).
🟠Двусторонний поток данных
Данные могут быть извлечены из DOM в любой момент времени, что делает управление состоянием менее очевидным.
Ставь 👍 и забирай 📚 Базу знанийmap(), который позволяет перебрать массив и вернуть JSX для каждого элемента. Это удобный и декларативный способ создания списков элементов.
🚩Пример использования `map()` для отрисовки массива
import React from 'react';
const users = [
{ id: 1, name: 'Alice', age: 25 },
{ id: 2, name: 'Bob', age: 30 },
{ id: 3, name: 'Charlie', age: 35 }
];
const UserList = () => {
return (
<div>
<h1>User List</h1>
<ul>
{users.map(user => (
<li key={user.id}>
{user.name} - {user.age} years old
</li>
))}
</ul>
</div>
);
};
export default UserList;
1⃣Использование map()
{users.map(user => (
<li key={user.id}>
{user.name} - {user.age} years old
</li>
))}
2⃣Атрибут key
<li key={user.id}>
🚩Отрисовка сложных компонентов
Если каждый элемент массива представляет собой более сложный компонент, можно создать отдельный компонент для каждого элемента и использовать его внутри map().
import React from 'react';
const users = [
{ id: 1, name: 'Alice', age: 25, email: 'alice@example.com' },
{ id: 2, name: 'Bob', age: 30, email: 'bob@example.com' },
{ id: 3, name: 'Charlie', age: 35, email: 'charlie@example.com' }
];
const UserItem = ({ user }) => {
return (
<div className="user-item">
<h2>{user.name}</h2>
<p>Age: {user.age}</p>
<p>Email: {user.email}</p>
</div>
);
};
const UserList = () => {
return (
<div>
<h1>User List</h1>
{users.map(user => (
<UserItem key={user.id} user={user} />
))}
</div>
);
};
export default UserList;
1⃣Создание компонента для элемента списка
const UserItem = ({ user }) => {
return (
<div className="user-item">
<h2>{user.name}</h2>
<p>Age: {user.age}</p>
<p>Email: {user.email}</p>
</div>
);
};
2⃣Использование компонента внутри map()
{users.map(user => (
<UserItem key={user.id} user={user} />
))}
Ставь 👍 и забирай 📚 Базу знанийsetState() может быть асинхронным. Это означает, что состояние компонента не обязательно будет обновлено сразу после вызова setState(). Вместо этого, React может сгруппировать несколько вызовов setState() для оптимизации производительности.
🟠Мерджинг состояния
При вызове setState() React сливает (мерджит) новый объект состояния с текущим состоянием. Это позволяет обновлять только те части состояния, которые изменились, без перезаписи всего состояния.
🚩Синтаксис
🟠Первый аргумент
Может быть объектом или функцией. Объект: Новый фрагмент состояния, который нужно объединить с текущим состоянием Функция: Функция, которая принимает текущее состояние и пропсы и возвращает новый фрагмент состояния.
🟠Второй аргумент (необязательный)
Колбэк-функция, которая будет вызвана после того, как состояние обновится и компонент перерисуется.
🚩Примеры использования
Объект как аргумент
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 0
};
}
incrementCount = () => {
this.setState({ count: this.state.count + 1 });
}
render() {
return (
<div>
<p>Count: {this.state.count}</p>
<button onClick={this.incrementCount}>Increment</button>
</div>
);
}
}
🟠Функция как аргумент
Использование функции вместо объекта рекомендуется, когда новое состояние зависит от предыдущего состояния, чтобы избежать потенциальных проблем с асинхронностью.
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 0
};
}
incrementCount = () => {
this.setState((prevState, props) => ({
count: prevState.count + 1
}));
}
render() {
return (
<div>
<p>Count: {this.state.count}</p>
<button onClick={this.incrementCount}>Increment</button>
</div>
);
}
}
🟠Колбэк-функция
Второй аргумент setState() — это колбэк, который вызывается после того, как состояние было обновлено и компонент перерисован.
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 0
};
}
incrementCount = () => {
this.setState({ count: this.state.count + 1 }, () => {
console.log('Состояние обновлено:', this.state.count);
});
}
render() {
return (
<div>
<p>Count: {this.state.count}</p>
<button onClick={this.incrementCount}>Increment</button>
</div>
);
}
}
🚩Важные замечания
🟠Не изменяйте состояние напрямую
Изменение состояния напрямую (например, this.state.count = 1) не вызовет перерисовку компонента. Всегда используйте setState().
🟠Batching (группировка)
React может группировать несколько вызовов setState() для повышения производительности. Поэтому состояние может быть обновлено асинхронно.
🟠Компоненты-классы и хуки
В функциональных компонентах для управления состоянием используются хуки, такие как useState. setState() используется только в компонентах-классах.
Ставь 👍 и забирай 📚 Базу знанийconst person = {
name: 'Alice',
age: 25
};
console.log(person.name); // 'Alice'
console.log(person.age); // 25
🟠Доступ через квадратные скобки
Квадратные скобки позволяют получать свойства с именами, которые могут содержать пробелы, специальные символы или быть результатом выражения. Это также полезно, когда имя свойства хранится в переменной.
const person = {
'first name': 'Alice',
age: 25
};
console.log(person['first name']); // 'Alice'
console.log(person['age']); // 25
const propertyName = 'age';
console.log(person[propertyName]); // 25
🟠Деструктуризация объектов
Деструктуризация позволяет извлекать свойства из объекта и присваивать их переменным. Это особенно полезно для извлечения нескольких свойств одновременно.
const person = {
name: 'Alice',
age: 25
};
const { name, age } = person;
console.log(name); // 'Alice'
console.log(age); // 25
🟠Использование Object.keys, Object.values и Object.entries
Эти методы позволяют получать массивы ключей, значений или пар ключ-значение соответственно.
Object.keys: Возвращает массив ключей объекта.
const person = {
name: 'Alice',
age: 25
};
const keys = Object.keys(person);
console.log(keys); // ['name', 'age']
Object.values: Возвращает массив значений объекта.
const person = {
name: 'Alice',
age: 25
};
const values = Object.values(person);
console.log(values); // ['Alice', 25]
Object.entries: Возвращает массив пар ключ-значение.
const person = {
name: 'Alice',
age: 25
};
const entries = Object.entries(person);
console.log(entries); // [['name', 'Alice'], ['age', 25]]
🟠Проверка наличия свойств
Перед доступом к свойству можно проверить его наличие с помощью оператора in или метода hasOwnProperty.
Оператор in
const person = {
name: 'Alice',
age: 25
};
console.log('name' in person); // true
console.log('gender' in person); // false
Метод hasOwnProperty
const person = {
name: 'Alice',
age: 25
};
console.log(person.hasOwnProperty('name')); // true
console.log(person.hasOwnProperty('gender')); // false
Ставь 👍 и забирай 📚 Базу знаний