React Flashcards

You may prefer our related Brainscape-certified flashcards:
1
Q

Что такое JSX?

A

JSX (JavaScript XML) - это расширение языка JavaScript, которое позволяет использовать XML-подобный синтаксис в React-приложениях. JSX — синтаксический сахар для функции React.createElement(component, props, …children). React приложения преобразуют JSX-код в обычный JavaScript-код с помощью компилятора.
Этот JSX-код:
return <Component />
…конвертируется в:
return React.createElement(SomeComponent, {a: 42, b: "testing"}, "Text Here")
…и результатом будет объект:
{ type: SomeComponent, props: {a: 42, b: "testing"}, children: ["Text Here"] }
За правильный парсинг и дальнейшую обработку отвечает babel.

Хотя JSX похож на HTML, это не HTML.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

Is it possible to use React without JSX?

A

Да, вместо JSX можно использовать обычный JavaScript, вызывая функции React напрямую. К пример, создать элемент можно с помощью React.createElement

// с использованием JSX function Greeting(props) { return <h1>Hello, {props.name}!</h1>; } // без использования JSX function Greeting(props) { return React.createElement('h1', null, Hello, ${props.name}!);

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

What is the virtual DOM? How does react use the virtual DOM to render the UI?

A

Реальный DOM (Real DOM) - это модель документа, которая представляет собой структуру дерева элементов на странице. Использование DOM снижает производительность приложения, т.к. после изменения элемента и его дочерних элементов требуется перерисовка всего пользовательского интерфейса.

Виртуальный DOM представляет собой виртуальное представление DOM. Если изменяется состояние какого-то элемента, создается новое виртуальное дерево DOM. Затем это дерево сравнивается с предыдущим виртуальным деревом DOM. Этот процесс называется “diffing” (сравнение различий).

Когда React знает, какие объекты виртуального DOM изменились, он обновляет только эти объекты в реальном DOM. Это гарантирует минимальное количество операций в реальном DOM и снижает затраты на обновление реального DOM в производительностном отношении.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

Являются ли виртуальный DOM и Shadow DOM одним и тем же?

A

Нет.

Виртуальный DOM – это концепция программирования, используемая для повышения производительности .

Shadow DOM - это технология браузера, разработанная для создания изолированных веб-компонентов с собственной структурой, стилями и поведением, чтобы избежать конфликтов с другими компонентами на странице.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

Чем отличается виртуальный DOM от реального DOM?

A
  1. Реальный/абстрактный: Реальный DOM - представляет структуру HTML-элементов на странице. Виртуальный DOM - не привязан к реальному документу и существует только в памяти компьютера.
  2. Обновление: Реальный DOM обновляется непосредственно в браузере при изменении состояния элементов на странице, в то время как виртуальный DOM обновляется в памяти компьютера.
  3. Производительность: Реальный DOM может быть медленным и затратным в обработке большого количества элементов и обновлений, так как каждое изменение может привести к перестройке и перерисовке всего дерева элементов. Виртуальный DOM более эффективен, так как он позволяет сначала обновлять виртуальное дерево элементов, а затем только те части реального DOM, которые изменились.
  4. Изоляция: Реальный DOM не предоставляет изоляции для компонентов на странице. Виртуальный DOM предоставляет изоляцию для компонентов, которые могут быть переиспользованы в разных частях страницы без конфликтов.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

When is a component rendered in React?

A

Процесс рендеринга в React запускается вызовом метода render() компонента. Этот метод возвращает описание того, как должен выглядеть компонент в виде дерева элементов React. Затем React использует это дерево и строит соответствующее дерево элементов DOM, которое добавляется в реальный DOM.
Когда состояние (state) или свойства (props) компонента изменяются, React автоматически перерендеривает компонент и обновляет DOM, чтобы отобразить изменения.

В React существуют методы жизненного - специальные функции, которые вызываются в определенные моменты жизни компонента, к примеру, когда компонент создается, обновляется или удаляется. Эти методы позволяют разработчикам управлять процессом рендеринга, определять, когда компонент должен быть обновлен, или выполнить дополнительные действия после обновления компонента.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

How not to render on props change?

A

Есть несколько способов избежать перерендеринга компонента при изменении его свойств (props)
1. Используйте shouldComponentUpdate() — этот метод жизненного цикла позволяет вам контролировать, должен ли компонент повторно отображаться.

class MyComponent extends React.Component { shouldComponentUpdate(nextProps) { if (this.props.myProp === nextProps.myProp) { return false; } return true; } render() { // ... } }

  1. Используйте PureComponent. PureComponent — это базовый класс для компонентов, который автоматически реализует shouldComponentUpdate() с поверхностным сравнением свойств и состояний.

class MyComponent extends React.PureComponent { render() { // ... } }

  1. Используйте функцию высшего порядка React.memo(). React.memo() — это higher-ordercomponent (HOC), который можно использовать для обертывания функционального компонента. Он работает аналогично PureComponent.
    Эта функция позволяет кэшировать результаты рендеринга компонента и перерендеривать его только тогда, когда изменяются его свойства.
    Чтобы использовать React.memo(), нужно обернуть компонент в эту функцию. Например:

import React from 'react'; const MyComponent = React.memo(props => { // Рендеринг компонента }); export default MyComponent;

Оберните компонент в мемо, чтобы получить мемоизированную версию этого компонента. Эта запомненная версия вашего компонента обычно не будет повторно отображаться при повторном отображении его родительского компонента, если его реквизиты не изменились. Но React все еще может перерендерить его: мемоизация — это оптимизация производительности, а не гарантия.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

Можно ли использовать стрелочные функции в методах рендеринга?

A

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

function MyComponent() { const handleClick = useCallback(() => { console.log('Button clicked'); }, []); return ( <div> <button onClick={handleClick}>Click me</button> </div> ); }

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

Как передать значение от дочернего к родительскому компоненту?

A

Передайте callback функцию в качестве свойства дочернему компоненту, которую дочерний компонент может вызвать

// Родительский компонент
function ParentComponent() {
function handleLanguageSelect(language) {
console.log(Выбран язык ${language});
}
//
return (
<div>
<h1>Родительский компонент</h1>
<SelectLanguage onLanguageSelect={handleLanguageSelect} />
</div>
);
}
//
// Дочерний компонент
function SelectLanguage(props) {
function handleChange(event) {
const selectedLanguage = event.target.value;
props.onLanguageSelect(selectedLanguage);
}
//
return (
<div>
<label>Выберите язык:</label>
<select id=”language-select” onChange={handleChange}>
<option>Английский</option>
<option>Французский</option
</select>
</div>
);
}</option>

Также можно через createContext или через редакс.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

Как передать значение от родительского к дочернему компоненту?

A

Передать значение через props, также, чтобы избежать prop drilling, можно передавать через createContext, или через редакс.

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

// Создаем контекст
const MyContext = React.createContext();
//
// Родительский компонент, который предоставляет значение через контекст
function ParentComponent() {
const valueToPass = “Hello, child!”; // значение, которое мы хотим передать
//
return (
<div>
<h1>Родительский компонент</h1>
<MyContext.Provider value={valueToPass}>
<ChildComponent></ChildComponent>
</MyContext.Provider>
</div>
);
}
//
// Дочерний компонент, который получает значение из контекста
function ChildComponent() {
return (
<div>
<h2>Дочерний компонент</h2>
<MyContext.Consumer>
{value => <p>{value}</p>}
</MyContext.Consumer>
</div>
);
}

Redux - это библиотека для управления состоянием приложения, которая позволяет хранить данные в глобальном хранилище (store) и обновлять их через действия (actions).

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q

Что такое “prop drilling”?

A

“Prop drilling” - это когда вы передаете свойства (props) от некоторого компонента FirstComponent к другому компоненту SecondComponent, которому на самом деле не нужны эти данные, и который только передает их дальше к компоненту ThirdComponent и, возможно, дальше по цепочке.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q

Может ли дочерний компонент изменять свои собственные свойства (props)?

A

Нет, не может. Он может менять state, но не может менять props.
Попытка изменения свойств может привести к ошибкам и нестабильному состоянию приложения.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q

Как передать значение от sibling к sibling?

A

Использовать “подъем состояния” (lifting state up) для передачи состояния из одного компонента в другой через родительский компонент.
Это позволяет обеспечить согласованность данных и упростить управление состоянием приложения.

function CounterWrapper() {
const [count, setCount] = useState(0);
//
const incrementCount = () => {
setCount(count + 1);
};
//
return (
<div>
<Counter count={count} />
<Button handleClick={incrementCount} />
</div>
);
}
//
function Counter({ count }) {
return (
<div>
<h1>{count}</h1>
</div>
);
}
//
function Button({ handleClick }) {
return (
<div>
<button onClick={handleClick}>Increment</button>
</div>
);
}

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
14
Q

В чем разница между props и state?

A

Props - это в основном параметры, с которыми инициализируется дочерний компонент. Эти параметры передаются дочернему от родительского компонента и являются неизменными. State принадлежит самому компоненту и управляется им. Состояние всегда инициализируется значением по умолчанию, и это значение может изменяться в течение жизненного цикла компонента в ответ на события. Когда состояние изменяется, компонент перерисовывается.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
15
Q

Как состояние (state) в классовом компоненте отличается от состояния в функциональном компоненте?

A

Объект state применялся только в классах-компонентах, а в функциональных используются хуки.

При использовании класса-компонента единственное место, где можно установить объект state - это конструктор класса. Для обновления состояния вызывается функция setState().

class Hello extends React.Component {
constructor(props) {
super(props);
this.state = {welcome: “Добро пожаловать на сайт!”};
}
render() {
return <h1>{this.state.welcome}</h1>;
}
}

Изменение состояния вызовет повторный рендеринг компонента, в соответствии с чем веб-страница будет обновлена.

this.setState({welcome: "Привет React"});

В функциональном компоненте используется хук useState, который вызывается каждый раз при рендеринге компонента. Он инициализирует состояние и метод изменения этого состояния.

import React, { useState } from ‘react’;
//
function Counter() {
const [count, setCount] = useState(0);
//
const handleIncrement = () => {
setCount(count+ 1);
};
//
return (
<div>
<h1>Count: {count}</h1>
<button onClick={handleIncrement}>Increment</button>
</div>
);
}
//
export default Counter;

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
16
Q

Что такое жизненный цикл компонента?

A
  1. Инициализация (Initialization):
    - constructor(): Метод конструктора компонента, в котором можно инициализировать состояние и привязывать методы к экземпляру компонента. Этот метод вызывается при создании компонента.
  2. Монтирование (Mounting):
    - componentDidMount(): Метод вызывается сразу после рендеринга компонента в DOM. Используется для выполнения сайд-эффектов, таких как загрузка данных с сервера, установка подписок на события или взаимодействие с DOM элементами.
    - static getDerivedStateFromProps(): Метод вызывается как на этапе монтирования, так и на этапе обновления. Он используется для обновления состояния компонента на основе новых свойств (props). Возвращает новое состояние на основе измененных свойств.
    - render(): Метод отрисовывает содержимое компонента и возвращает JSX элементы.
  3. Обновление (Updating):
    - shouldComponentUpdate(): Метод вызывается при попытке обновить компонент. Он определяет, должен ли компонент обновиться и перерисоваться после изменения состояния или свойств. Используется для оптимизации производительности путем предотвращения ненужных перерисовок.
    - componentDidUpdate(): Метод вызывается после выполнения обновлений компонента в DOM. Используется для выполнения дополнительных сайд-эффектов, таких как выполнение запросов к API или обновление внешних библиотек.
    - static getDerivedStateFromProps(): Метод вызывается как на этапе монтирования, так и на этапе обновления. Он используется для обновления состояния компонента на основе новых свойств (props). Возвращает новое состояние на основе измененных свойств.
    - render(): Метод обновляет отображение компонента.
    - getSnapshotBeforeUpdate(): Метод вызывается прямо перед применением обновлений к DOM. Он позволяет компоненту захватить текущее состояние DOM перед изменениями, такими как прокрутка или позиция фокуса. Возвращает значение, которое будет передано методу componentDidUpdate().
  4. Размонтирование (Unmounting):
    - componentWillUnmount(): Метод вызывается перед удалением компонента из DOM. Используется для очистки ресурсов, отписки от событий или отмены таймеров.

Используя методы жизненного цикла классовых компонентов или hook useEffect в функциональных компонентах, мы можем запускать код в определенные моменты жизни компонента.

  1. Монтирование:
    - useEffect(() => {}, []): Этот хук сработает только один раз после первого рендеринга компонента, аналогично методу componentDidMount. Здесь можно инициализировать состояние, подписываться на события или выполнять другие сайд-эффекты.
  2. Обновление:
    - useEffect(() => {}): Этот хук сработает после каждого рендеринга компонента, аналогично методу componentDidUpdate. Здесь можно обрабатывать изменения состояния или свойств и выполнять соответствующие действия.
    - useMemo(() => {}, [dependency]): Этот хук служит для мемоизации значений и повышения производительности, аналогично использованию shouldComponentUpdate. Он вычисляет и возвращает значение только в том случае, если его зависимость изменилась.
  3. Размонтирование:
    - useEffect(() => { return () => {} }, []): Этот хук сработает перед размонтированием компонента, аналогично методу componentWillUnmount. Здесь можно выполнять очистку ресурсов, отписку от событий или выполнение других необходимых действий перед удалением компонента из DOM.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
17
Q

Как обновить жизненный цикл в функциональных компонентах?

A

Используя hook useEffect.

useEffect принимает два аргумента: колбэк-функцию, которая содержит код побочного эффекта, и массив зависимостей. Колбэк-функция запускается после каждого рендеринга компонента. Если массив зависимостей передан, то эффект запускается только в том случае, если значения в массиве изменились с момента последнего запуска эффекта.
с помощью хука useEffect можно имитировать методы жизненного цикла componentDidMount, componentDidUpdate и componentWillUnmount.

// метод componentDidMount useEffect(() => { console.log('Component mounted'); }, []); // // метод componentDidUpdate useEffect(() => { console.log('Component updated'); }, [count]); // // метод componentWillUnmount useEffect(() => { return () => { console.log('Component unmounted'); } }, []);

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
18
Q

Какова разница между refs и переменными состояния (state)?

A

И refs, и переменные состояния сохраняют значения между рендерами, но только переменные состояния вызывают повторный рендер компонента.
ref может быть использован для получения доступа к методам и свойствам компонента, которые не являются доступными через его props. Например, ref можно использовать для получения ссылки на поле ввода (<input></input>) и вызова метода focus() для установки фокуса на него.
Хук useRef позволяет сохранить некоторый объект, который можно изменять и который хранится в течение всей жизни компонента. В качестве параметра функция useRef() принимает начальное значение хранимого объекта. А возвращаемое значение - ссылка-объект, из свойства current которого можно получить хранимое значение.

const refUser = useRef("Tom"); console.log(refUser.current); // Tom <input type="text" ref={ refUser } />

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
19
Q

Когда лучше всего использовать refs?

A

Один из способов использования refs - это прямой доступ к элементу DOM для его манипулирования. Например, это может быть необходимо при интеграции с сторонней библиотекой DOM или для запуска императивных анимаций.

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

Использовать refs советуют только при необходимости, чтобы избежать нарушения инкапсуляции.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
20
Q

Как правильно обновлять ref в функциональном компоненте?

A

С помощью hook useRef! А в классовых с помощью React.createRef().

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
21
Q

Какова разница между API контекста и prop drilling? Когда не следует использовать API контекста?

A

Prop drilling - это процесс передачи данных от компонента к компоненту через пропсы. Если компонент A должен передать данные компоненту C, но компонент B находится между ними, то компонент A должен передать данные через пропсы компоненту B, а затем компонент B должен передать эти данные компоненту C через его пропсы. Этот процесс может стать громоздким и неудобочитаемым, особенно если компонентов много.

API контекста дает нам централизованное хранилище данных, к которому мы можем неявно обращаться, используя метод contextType или хук useContext, чтобы получать данные из любого компонента. Основным недостатком API контекста является то, что каждый раз, когда контекст меняется, все компоненты, потребляющие значение, перерисовываются. Это может иметь отрицательные последствия для производительности. По этой причине следует использовать API контекста только для редко обновляемых данных, таких как настройки темы.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
22
Q

Redux

A

Основная идея redux заключается в том, что все состояние приложения хранится в одном хранилище. Store (хранилище) - это просто JavaScript объект.
Единственный способ изменить состояние — отправить действие (action) из вашего приложения, а затем написать редьюсеры для этих действий, которые изменяют состояние.
Весь переход состояния хранится внутри редьюсеров и не должен иметь никаких побочных эффектов.

Основные принципы Redux включают единообразность состояния, неизменяемость состояния и предсказуемость изменений состояния.

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

Неизменяемость состояния означает, что состояние не должно изменяться напрямую. Вместо этого, каждый раз при изменении состояния создается новый объект состояния. Это позволяет удобно отслеживать изменения состояния и уменьшает вероятность ошибок, связанных с изменением состояния напрямую. Все обновления состояния выполняются через действия (actions), которые передаются в store через dispatch и reducers.

Предсказуемость изменений состояния означает, что все изменения предсказуемы и могут быть отслеживаемыми. Это реализуется за счет редукторов – чистых функций. Таким образом, мы можем легко отследить, какие изменения произошли в состоянии в ответ на действия или внешние события.

import { createStore } from 'redux'; // // Определяем начальное состояние const initialState = { counter: 0 }; // // Определяем reducer function counterReducer(state = initialState, action) { switch (action.type) { case 'INCREMENT': return { ...state, counter: state.counter + 1 }; case 'DECREMENT': return { ...state, counter: state.counter - 1 }; default: return state; } } // // Создаем store const store = createStore(counterReducer); // function App() { // Получаем текущее значение состояния const counter = store.getState().counter; // // Диспатчим действия const increment = () => store.dispatch({ type: 'INCREMENT' }); const// Диспатчим действия const decrement = () => store.dispatch({ type: 'DECREMENT' }); // return ( <div> <h1>Counter: {counter}</h1> <button onClick={increment}>Increment</button> <button onClick={decrement}>Decrement</button> </div> ); }

В этом примере мы создаем начальное состояние, определяем reducer, который определяет, какие действия могут изменять состояние, и создаем store, который хранит состояние приложения. Затем мы создаем компонент App, который получает текущее значение состояния из store и диспатчит действия для изменения состояния.
Когда мы вызываем функцию increment или decrement, мы отправляем действие в store, которое вызывает reducer. Редьюсер изменяет состояние в соответствии с переданным действием, и store обновляет состояние приложения. Затем компонент App перерисовывается, чтобы отобразить новое значение состояния.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
23
Q

Каков типичный поток данных в приложении React + Redux?

A
  1. Начальная настройка:
    * Store Redux создается с использованием функции корневого редуктора и сохраняет возвращаемое значение как начальное состояние (state)

const rootReducer = combineReducers({
counter: counterReducer,
todos: todoReducer
});

  • Компоненты пользовательского интерфейса получают доступ к текущему состоянию хранилища Redux и используют эти данные, чтобы решить, что отображать. Они также подписываются на любые будущие обновления store, чтобы знать, изменилось ли состояние.

const count = useSelector(state => state.counter);

  1. Обновления:
    * Что-то происходит в приложении, например, пользователь нажимает кнопку и код приложения отправляет действие в store Redux через dispatch, например
    *
    dispatch({type: ‘counter/incremented’})
  • Store снова запускает функцию редуктора с предыдущим state и текущим action и сохраняет возвращаемое значение как новое state
  • Store уведомляет все части пользовательского интерфейса, на которые оформлена подписка, об обновлении.
  • Каждый компонент пользовательского интерфейса, которому нужны данные из хранилища, проверяет, не изменились ли нужные им части состояния.
  • Каждый компонент, который видит, что его данные изменились, вызывает повторный рендер с новыми данными.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
24
Q

Технические преимущества использования Redux.

A
  1. Легкий перенос состояния между компонентами
  2. Предсказуемые состояния - если одно и то же состояние и действие передаются в редьюсер, то генерируется одинаковый результат, так как функции редьюсера являются чистыми. Это позволяет выполнять сложные задачи, такие как постоянное отмена и повторение действий. Доступны также временные путешествия, которые могут перемещаться вперед и назад между предыдущими состояниями, и результаты можно просматривать в режиме реального времени
  3. Может быть использован для рендеринга на стороне сервера. Просто передайте созданный на сервере store на сторону клиента.
  4. Большое количество инструментов разработчика
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
25
Q

Это хорошая идея использовать Math.random для ключей?

A

Использование Math.random() для генерации ключей не является хорошей идеей, так как это может привести к возникновению коллизий и дубликатов ключей.
Вместо этого можно использовать данные из базы данных, UUID или другую библиотеку.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
26
Q

Каковы ограничения React?

A

React считается относительно тяжелой зависимостью и может быть избыточным для небольших приложений.
В React команды зависят от дополнительных библиотек для получения данных, таких как Axios или Fetch.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
27
Q

Что такое Higher Order Component, HOC?

A

Это функция, которая принимает компонент и возвращает новый модифицированный компонент.
Хотя HOC’ы ассоциируются с React, они не являются функцией React, а скорее являются паттерном, вдохновленным функциональным программированием, называемым функциями более высокого порядка.

Один из примеров HOC с открытым исходным кодом - это React Sortable HOC, при котором вы передаете компонент списка (на основе ul) и получаете улучшенный ul с возможностями сортировки и перетаскивания.

import React from "react"; // // HOC, который добавляет стиль к компоненту function withStyle(WrappedComponent, style) { return function(props) { return ( <div style={style}> <WrappedComponent {...props} /> </div> ); }; } // // Компонент, который мы будем оборачивать function MyComponent(props) { return <h1>Hello, {props.name}!</h1>; } // // Оборачиваем MyComponent в HOC с заданным стилем const StyledComponent = withStyle(MyComponent, { color: "red" }); // // Используем оба компонента function App() { return ( <div> <MyComponent name="Alice" /> <StyledComponent name="Bob" /> </div> ); } // export default App;

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
28
Q

Что такое Controlled and Uncontrolled Components?

A

В HTML элементы формы, такие как input, textarea и select, обычно сами управляют своим состоянием и обновляют его когда пользователь вводит данные. В React мутабельное состояние обычно содержится в свойстве компонентов state и обновляется только через вызов setState().

Управляемый компонент - это компонент ввода, такой как input, textarea или select, значение которого контролируется React.

Чтобы взять под контроль этот компонент в React, вам нужно подписаться на событие onChange у textarea и обновлять переменную состояния (например, называемую input) в ответ на это событие.
Теперь React управляет значением textarea, поэтому вам также нужно взять на себя ответственность за установку свойства value для textarea.

Неуправляемый компонент управляет своим собственным состоянием - компонент не контролируется React и, следовательно, является “неуправляемым”.

Представьте, что вы добавили на страницу textarea и начали печатать. Все, что вы печатаете, будет автоматически сохраняться в textarea и будет доступно через его свойство value. Хотя React может получить доступ к значению с помощью ref, но React не контролирует значение в этом случае. Это будет примером неуправляемого компонента. Неуправляемые компоненты опираются на DOM в качестве источника данных и могут быть удобны при интеграции React с кодом, не связанным с React. Количество кода может уменьшиться, правда, за счёт потери в его чистоте. Поэтому в обычных ситуациях мы рекомендуем использовать управляемые компоненты.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
29
Q

Оптимизация производительности для приложений React

A
  1. Используйте PureComponent или React.memo: PureComponent и React.memo предоставляют оптимизированную реализацию метода shouldComponentUpdate, что позволяет уменьшить количество лишних перерисовок компонентов.
  2. Используйте React.lazy()
    Ленивая загрузка позволяет разбить приложение на небольшие фрагменты, которые загружаются по мере необходимости. Это помогает ускорить время загрузки и уменьшить объем передаваемых данных.

import React, { lazy, Suspense } from 'react'; // const LazyComponent = lazy(() => import('./LazyComponent')); // function App() { return ( <div> <Suspense fallback={<div>Loading...</div>}> <LazyComponent /> </Suspense> </div> ); } // export default App;

  1. Using Production Mode Flag in Webpack
    Если вы используете webpack 4 в качестве сборщика модулей для своего приложения, вы можете установить mode в режим производства, что говорит веб-пакету использовать встроенную оптимизацию:module.exports = { mode: 'production' };
  2. Используйте виртуализацию списка:

Виртуализация списка позволяет отображать только те элементы списка, которые видны на экране, а не все элементы сразу. Это может существенно ускорить время отрисовки больших списков.

import React from 'react'; import { FixedSizeList } from 'react-window'; // function MyList(props) { const { items } = props; // const Row = ({ index, style }) => ( <div style={style}>{items[index]}</div> ); // return ( <FixedSizeList height={400} itemCount={items.length} itemSize={50} width={300} > {Row} </FixedSizeList> ); } // export default MyList;

  1. Оптимизация зависимостей
    При рассмотрении вопроса об оптимизации размера пакета приложения стоит проверить, сколько кода вы фактически используете из зависимостей. Например, вы можете использовать Moment.js, который включает локализованные файлы для многоязычной поддержки. Если вам не нужно поддерживать несколько языков, вы можете рассмотреть возможность использования плагина moment-locales-webpack-plugin, чтобы удалить неиспользуемые локали для вашего окончательного пакета. Другой пример — loadash. Допустим, вы используете только 20 из 100+ методов, тогда наличие всех дополнительных методов в окончательном пакете не является оптимальным. Так что для этого вы можете использовать lodash-webpack-plugin для удаления неиспользуемых функций. Вот обширный список зависимостей, которые вы можете оптимизировать.
  2. Используйте React.Fragments, чтобы избежать дополнительных оболочек HTML-элементов
    React.fragments позволяет группировать список дочерних элементов без добавления дополнительного узла.

class Comments extends React.PureComponent{ render() { return ( <React.Fragment> <h1>Comment Title</h1> <p>comments</p> <p>comment time</p> </React.Fragment> ); } }

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

default class CommentList extends React.Component { state = { comments: [], selectedCommentId: null } // render(){ const { comments } = this.state; return ( comments.map((comment)=>{ return <Comment onClick={(e)=>{ this.setState({selectedCommentId:comment.commentId}) }} comment={comment} key={comment.id}/> }) ) } }

Вместо определения встроенной функции для реквизита вы можете определить функцию стрелки.

default class CommentList extends React.Component { state = { comments: [], selectedCommentId: null } // onCommentClick = (commentId)=>{ this.setState({selectedCommentId:commentId}) } // render(){ const { comments } = this.state; return ( comments.map((comment)=>{ return <Comment onClick={this.onCommentClick} comment={comment} key={comment.id}/> }) ) } }

  1. Избегайте использования индекса в качестве key
    Так как это может вызвать проблемы, к примеру, при удалении элемента.
  2. Memoize React Components
    Мемоизация — это метод оптимизации, используемый в основном для ускорения работы компьютерных программ за счет сохранения результатов дорогостоящих вызовов функций и возврата кэшированного результата при повторении тех же входных данных. Запоминаемая функция обычно быстрее, потому что если функция вызывается с теми же значениями, что и предыдущая, то вместо выполнения логики функции она будет извлекать результат из кеша.

const UserDetails = ({user, onEdit}) => { const {title, full_name, profile_img} = user; // return ( <div className="user-detail-wrapper"> <img src={profile_img} /> <h4>{full_name}</h4> <p>{title}</p> </div> ) }

Здесь все дочерние элементы в UserDetails основаны на свойствах. Этот компонент без сохранения состояния будет перерисовываться при изменении свойства. Если маловероятно, что атрибут компонента UserDetails изменится, то он является хорошим кандидатом на использование memoize-версии компонента:

const UserDetails = ({user, onEdit}) =>{ const {title, full_name, profile_img} = user; // return ( <div className="user-detail-wrapper"> <img src={profile_img} /> <h4>{full_name}</h4> <p>{title}</p> </div> ) } // export default React.memo(UserDetails)

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
30
Q

Перечислить встроенные хуки React рассказать о каждом подробнее

A
  1. useState:
    Хук useState позволяет добавлять и использовать состояние в функциональных компонентах. Он возвращает пару значений: текущее состояние и функцию для его обновления. Пример:import React, { useState } from 'react'; // const Counter = () => { const [count, setCount] = useState(0); // const increment = () => { setCount(count + 1); }; // return ( <div> <p>Count: {count}</p> <button onClick={increment}>Increment</button> </div> ); };
  2. useEffect:
    Хук useEffect позволяет выполнять побочные эффекты в функциональных компонентах, также используется как аналог методов жизненного цикла для функциональных компонентов. Пример:import React, { useState, useEffect } from 'react'; // const Timer = () => { const [seconds, setSeconds] = useState(0); // useEffect(() => { const intervalId = setInterval(() => { setSeconds((prevSeconds) => prevSeconds + 1); }, 1000); // return () => { clearInterval(intervalId); }; }, []); // пустой массив зависимостей означает, что эффект будет выполнен только при монтировании и размонтировании компонента // return <p>Seconds: {seconds}</p>; };
  3. useContext:
    Хук useContext позволяет получить значение из контекста React в функциональных компонентах, без необходимости передавать данные через пропсы. Он принимает объект контекста, созданный с помощью React.createContext, и возвращает текущее значение контекста. Пример:import React, { useContext } from 'react'; // const ThemeContext = React.createContext('light'); // const ThemedButton = () => { const theme = useContext(ThemeContext); // return <button>{theme}</button>; }; // const App = () => { return ( <ThemeContext.Provider value="dark"> <ThemedButton /> </ThemeContext.Provider> ); };
  4. useReducer:
    Хук useReducer позволяет управлять состоянием компонента с помощью паттерна “редюсер”. Этот хук похож на useState, но предоставляет более мощный способ обновления состояния, особенно при сложных или зависимых от предыдущего состояния операциях. Он возвращает текущее состояние и функцию для его обновления, также как и useState. Пример:

import React, { useReducer } from 'react'; // const initialState = { count: 0 }; // const 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); // const increment = () => { dispatch({ type: 'increment' }); }; // const decrement = () => { dispatch({ type: 'decrement' }); }; // return ( <div> <p>Count: {state.count}</p> <button onClick={increment}>Increment</button> <button onClick={decrement}>Decrement</button> </div> ); };

  1. useCallback:
    Хук useCallback позволяет кэшировать функцию, чтобы она сохраняла тот же экземпляр между рендерами компонента. Он позволяет кешировать функцию и перерасчет её значения, только когда изменяются зависимости. Это полезно, когда вы передаете функцию в дочерние компоненты с помощью пропсов, чтобы избежать ненужных перерисовок. Пример:import React, { useState, useCallback } from 'react'; // const CounterButton = ({ onClick }) => { // Колбэк-функция будет сохраняться между рендерами return <button onClick={onClick}>Increment</button>; }; // const Counter = () => { const [count, setCount] = useState(0); // const increment = useCallback(() => { setCount((prevCount) => prevCount + 1); }, []); // return ( <div> <p>Count: {count}</p> <CounterButton onClick={increment} /> </div> ); };
  2. useMemo:
    Хук useMemo позволяет кэшировать вычисленное значение, чтобы оно сохранялось между рендерами компонента. Это полезно, когда вы должны вычислить сложное или ресурсоемкое значение, которое затем используется в компоненте. Пример:

import React, { useMemo } from 'react'; // const ExpensiveComponent = ({ number }) => { // Расчет затратного значения будет выполняться только тогда, когда // number изменится const expensiveValue = useMemo(() => { // Вычисления затратного значения return calculateExpensiveValue(number); }, [number]); // return <p>Expensive Value: {expensiveValue}</p>; }; // const App = () => { const number = 42; // return <ExpensiveComponent number={number} />; };

  1. useRef:
    useRef позволяет получать доступ к DOM-элементам, а также хранить и получать значения этих элементов. Не вызывает ререндер компонента. Хук useRef возвращает изменяемый объект с полем current, которое может быть использовано для хранения мутирующих значений, которые не вызывают перерисовку компонента. Он полезен для сохранения/изменения значений между рендерами, обработки фокуса ввода или получения ссылок на DOM-элементы. Пример:import React, { useRef } from 'react'; // const TextInput = () => { const inputRef = useRef(); // const focusInput = () => { inputRef.current.focus(); }; // return ( <div> <input type="text" ref={inputRef} /> <button onClick={focusInput}>Focus Input</button> </div> ); };
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
31
Q

Что можно сделать с помощью useReducer, чего нельзя сделать с помощью useState?

A

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

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
32
Q

Что такое batchUpdate и как он работает в React? Как решить проблему с тем что в функциональной компоненте в асинхронной функции при вызове setState - не работает batch update?

A

Batch update - это механизм оптимизации производительности в React, который позволяет обновлять компоненты пакетами вместо того, чтобы вызывать рендеринг после каждого изменения состояния. Чтобы решить проблему можно сгруппировать переменные состояния в один объект и использовать useReducer с этим объектом.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
33
Q

Какие способы предотвращения ререндеров компонента существуют?

A

React.memo, PureComponent, shouldComponentUpdate, useCallback и useMemo и использование useRef

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
34
Q

Какие есть недостатки в React?

A

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

35
Q

Какие методы жизненного цикла компонента существуют в React?

A

render() — единственный обязательный метод в классовом компоненте.
При вызове он проверяет this.props и this.state и возвращает один из следующих вариантов: Элемент React, Массивы и фрагменты, Порталы, Строки и числа, Booleans или null

constructor() - Конструктор компонента React вызывается до того, как компонент будет примонтирован. В начале конструктора необходимо вызывать super(props). Если это не сделать, this.props не будет определён. Это может привести к багам.
Конструкторы в React обычно используют для двух целей: Инициализация внутреннего состояния через присвоение объекта this.state. Привязка обработчиков событий к экземпляру.
Конструктор — единственное место, где можно напрямую изменять this.state. В остальных методах необходимо использовать this.setState().

componentDidMount() - вызывается сразу после монтирования (то есть, вставки компонента в DOM). В этом методе должны происходить действия, которые требуют наличия DOM-узлов. Это хорошее место для создания сетевых запросов.
Этот метод подходит для настройки подписок. Но не забудьте отписаться от них в componentWillUnmount().

componentDidUpdate(prevProps, prevState, snapshot) - вызывается сразу после обновления. Не вызывается при первом рендере. Метод позволяет работать с DOM при обновлении компонента. Также он подходит для выполнения таких сетевых запросов, которые выполняются на основании результата сравнения текущих пропсов с предыдущими. Если пропсы не изменились, новый запрос может и не требоваться.

componentWillUnmount() - вызывается непосредственно перед размонтированием и удалением компонента. В этом методе выполняется необходимый сброс: отмена таймеров, сетевых запросов и подписок, созданных в componentDidMount().

shouldComponentUpdate(nextProps, nextState) - вызывается перед рендером, когда получает новые пропсы или состояние. Значение по умолчанию равно true. Этот метод нужен только для повышения производительности.. Но не опирайтесь на его возможность «предотвратить» рендер, это может привести к багам. Вместо этого используйте PureComponent, который позволяет не описывать поведение shouldComponentUpdate() вручную. PureComponent поверхностно сравнивает пропсы и состояние и позволяет не пропустить необходимое обновление.

static getDerivedStateFromProps(props, state) - вызывается непосредственно перед вызовом метода render, как при начальном монтировании, так и при последующих обновлениях. Он должен вернуть объект для обновления состояния или null, чтобы ничего не обновлять.
Этот метод существует для редких случаев, когда состояние зависит от изменений в пропсах.

getSnapshotBeforeUpdate(prevProps, prevState) - вызывается прямо перед этапом «фиксирования» (например, перед добавлением в DOM). Он позволяет вашему компоненту брать некоторую информацию из DOM (например, положение прокрутки) перед её возможным изменением. Любое значение, возвращаемое этим методом жизненного цикла, будет передано как параметр componentDidUpdate().

static getDerivedStateFromError(error) - Этот метод жизненного цикла вызывается после возникновения ошибки у компонента-потомка. Он получает ошибку в качестве параметра и возвращает значение для обновления состояния. getDerivedStateFromError() вызывается во время этапа «рендера». Поэтому здесь запрещены любые побочные эффекты, но их можно использовать в componentDidCatch().

componentDidCatch(error, info) - Этот метод жизненного цикла вызывается после возникновения ошибки у компонента-потомка. Он получает два параметра: error — перехваченная ошибка, info — объект с ключом componentStack, содержащий информацию о компоненте, в котором произошла ошибка. Метод можно использовать для логирования ошибок.

36
Q

Что такое Context в React и для чего он используется?

A

Контекст разработан для передачи данных, которые можно назвать «глобальными» для всего дерева React-компонентов (например, текущий аутентифицированный пользователь, UI-тема или выбранный язык).

Контекст позволяет избежать передачи пропсов в промежуточные компоненты:

// Контекст позволяет передавать значение глубоко
// в дерево компонентов без явной передачи пропсов
// на каждом уровне. Создадим контекст для текущей
// UI-темы (со значением “light” по умолчанию).
const ThemeContext = React.createContext(‘light’);

class App extends React.Component {
render() {
// Компонент Provider используется для передачи текущей
// UI-темы вниз по дереву. Любой компонент может использовать
// этот контекст и не важно, как глубоко он находится.
// В этом примере мы передаём “dark” в качестве значения контекста.
return (
<ThemeContext.Provider>
<Toolbar></Toolbar>
</ThemeContext.Provider>
);
}
}

// Компонент, который находится в середине,
// теперь не должен явно передавать UI-тему вниз.
function Toolbar(props) {
return (
<div>
<ThemedButton></ThemedButton>
</div>
);
}

class ThemedButton extends React.Component {
// Определяем contextType, чтобы получить значение контекста.
// React найдёт (выше по дереву) ближайший Provider-компонент,
// предоставляющий этот контекст, и использует его значение.
// В этом примере значение UI-темы будет “dark”.
static contextType = ThemeContext;
render() {
return <Button theme={this.context} />;
}
}
Обычно контекст используется, если необходимо обеспечить доступ данных во многих компонентах на разных уровнях вложенности. По возможности не используйте его, так как это усложняет переиспользование компонентов.

API:
React.createContext - оздание объекта Context. Когда React рендерит компонент, который подписан на этот объект, React получит текущее значение контекста из ближайшего подходящего Provider выше в дереве компонентов.
Context.Provider - Каждый объект Контекста используется вместе с Provider компонентом, который позволяет дочерним компонентам, использующим этот контекст, подписаться на его изменения.
Class.contextType - В свойство класса contextType может быть назначен объект контекста, созданный с помощью React.createContext(). Это позволяет вам использовать ближайшее и актуальное значение указанного контекста при помощи this.context. В этом случае вы получаете доступ к контексту, как во всех методах жизненного цикла, так и в рендер методе.
Context.Consumer - Consumer — это React-компонент, который подписывается на изменения контекста. В свою очередь, это позволяет вам подписаться на контекст в функциональном компоненте. Consumer принимает функцию в качестве дочернего компонента. Эта функция принимает текущее значение контекста и возвращает React-компонент. Передаваемый аргумент value будет равен ближайшему (вверх по дереву) значению этого контекста, а именно пропу value Provider компонента. Если такого Provider компонента не существует, аргумент value будет равен значению defaultValue, которое было передано в createContext().

37
Q

Для чего нужен атрибут key при рендере списков?

A

Ключи (keys) помогают React определять, какие элементы были изменены, добавлены или удалены. Их необходимо указывать, чтобы React мог сопоставлять элементы массива с течением времени.

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

38
Q

Как работает проп children?

A

Некоторые компоненты не знают своих потомков заранее. Это особенно характерно для таких компонентов, как Sidebar или Dialog, которые представляют из себя как бы «коробку», в которую можно что-то положить. Для таких компонентов мы рекомендуем использовать специальный проп children, который передаст дочерние элементы сразу на вывод:

function FancyBorder(props) { return ( <div className={'FancyBorder FancyBorder-' + props.color}> {props.children} </div> ); }

Это позволит передать компоненту произвольные дочерние элементы, вложив их в JSX:

function WelcomeDialog() { return ( <FancyBorder color="blue"> <h1 className="Dialog-title"> Добро пожаловать </h1> <p className="Dialog-message"> Спасибо, что посетили наш космический корабль! </p> </FancyBorder> ); }

Всё, что находится внутри JSX-тега , передаётся в компонент FancyBorder через проп children. Поскольку FancyBorder рендерит {props.children} внутри div, все переданные элементы отображаются в конечном выводе.

39
Q

Что такое PureComponent?

A

React.PureComponent похож на React.Component. Отличие заключается в том, что React.Component не реализует shouldComponentUpdate(), а React.PureComponent реализует его поверхностным сравнением пропсов и состояния.

Если метод render() вашего React-компонента всегда рендерит одинаковый результат при одних и тех же пропсах и состояниях, для повышения производительности в некоторых случаях вы можете использовать React.PureComponent.

Метод shouldComponentUpdate() базового класса React.PureComponent делает только поверхностное сравнение объектов. Если они содержат сложные структуры данных, это может привести к неправильной работе для более глубоких различий (то есть, различий, не выраженных на поверхности структуры). Наследуйте класс PureComponent только тогда, когда вы ожидаете использовать простые пропсы и состояние

40
Q

Что такое порталы в React?

A

Порталы позволяют рендерить дочерние элементы в DOM-узел, который находится вне DOM-иерархии родительского компонента.

ReactDOM.createPortal(child, container)
Первый аргумент (child) — это любой React-компонент, который может быть отрендерен, такой как элемент, строка или фрагмент. Следующий аргумент (container) — это DOM-элемент.

Типовой случай применения порталов — когда в родительском компоненте заданы стили overflow: hidden или z-index, но вам нужно чтобы дочерний элемент визуально выходил за рамки своего контейнера. Например, диалоги, всплывающие карточки и всплывающие подсказки.

41
Q

Что такое React Reconciliation (Cверка) и как он работает?

A

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

При сравнении двух деревьев первым делом React сравнивает два корневых элемента. Поведение различается в зависимости от типов корневых элементов.

Всякий раз, когда корневые элементы имеют различные типы, React уничтожает старое дерево и строит новое с нуля.

При сравнении двух React DOM-элементов одного типа, React смотрит на атрибуты обоих, сохраняет лежащий в основе этих элементов DOM-узел и обновляет только изменённые атрибуты.

По умолчанию при рекурсивном обходе дочерних элементов DOM-узла React проходит по обоим спискам потомков одновременно и создаёт мутацию, когда находит отличие. Эта неэффективность может стать проблемой. Когда у дочерних элементов есть ключи, React использует их, чтобы сопоставить потомков исходного дерева с потомками последующего дерева.

42
Q

Можно создавать анимации в React?

A

React может использоваться для создания крутых анимаций! В качестве примера посмотрите библиотеки React Transition Group и React Motion.

43
Q

Что такое Flux - архитектура? Какие сущности она имеет?

A

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

Основной отличительной особенностью Flux является односторонняя направленность передачи данных между компонентами Flux-архитектуры. Архитектура накладывает ограничения на поток данных, в частности, исключая возможность обновления состояния компонентов самими собой. Такой подход делает поток данных предсказуемым и позволяет легче проследить причины возможных ошибок в программном обеспечении.

В минимальном варианте Flux-архитектура может содержать три слоя, взаимодействующие по порядку:

Действия (англ. actions) — выражение событий (часто для действий используются просто имена — строки, содержащие некоторый «глагол»). Диспетчеры передают действия нижележащим компонентам (хранилищам) по одному. Новое действие не передаётся пока предыдущее полностью не обработано компонентами. Действия из-за работы источника действия, например, пользователя, поступают асинхронно, но их диспетчеризация является синхронным процессом. Кроме имени (англ. name), действия могут иметь полезную нагрузку (англ. payload), содержащую относящиеся к действию данные.

Диспетчер/Диспатчер (англ. dispatcher) предназначен для передачи действий хранилищам. В упрощённом варианте диспетчер может вообще не выделяться, как единственный на всё приложение. В диспетчере хранилища регистрируют свои функции обратного вызова (callback) и зависимости между хранилищами.

Хранилище (англ. store) является местом, где сосредоточено состояние (англ. state) приложения. Остальные компоненты, согласно Flux, не имеют значимого (с точки зрения архитектуры) состояния. Изменение состояния хранилища происходит строго на основе данных действия и старого состояния хранилища при помощи чистых функций.

Представление (англ. view) — компонент, обычно отвечающий за выдачу информации пользователю. Во Flux-архитектуре, которая может технически не касаться внутреннего устройства представлений вообще, это — конечная точка потоков данных. Для информационной архитектуры важно только, что данные попадают в систему (то есть, обратно в хранилища) только через действия.

44
Q

Lazy loading, code splitting

A

Lazy loading - ленивая загрузка, для того чтобы загружать очередной бандл по требованию. Эта оптимизация полезна т.к. не все части приложения могут пригодится сразу же. Таким образом мы можем ускорить загрузку сайта за счет меньшего размера бандла.

Бандлы - это результат работы работы сборщиков проекта (Webpack, Rollup). Сама сборка - это процесс выявления импортированных файлов и объединения их в один файл (часто называемый “bundle” или “бандл”). Этот бандл после подключения на веб-страницу загружает приложение.
Однако нужно следить за размером бандла - любая подключенная библиотека добавляет лишний килобайты. И загрузка может занять слишком много времени. При помощи сборщиков проекта можно создавать несколько бандлов и загружать их по мере необходимости. Общий размер кода не уменьшится (он будет разделен на несколько частей) - однако начальная загрузка будет быстрее.
React.lazy
const OtherComponent = React.lazy(() => import(‘./OtherComponent’))
Она автоматически загрузит бандл, содержащий OtherComponent, когда этот компонент будет впервые отрендерен.

React.lazy принимает функцию, которая должна вызвать динамический import(). Результатом возвращённого Promise является модуль, который экспортирует по умолчанию React-компонент (export default).

Suspense
Компонент с ленивой загрузкой должен рендериться внутри компонента Suspense, который позволяет нам показать запасное содержимое (например, индикатор загрузки) пока происходит загрузка ленивого компонента.

Предохранители (error boundary)
Если какой-то модуль не загружается (например, из-за сбоя сети), это вызовет ошибку. Можно обрабатывать эти ошибки для улучшения пользовательского опыта с помощью предохранителей.

45
Q

setState синхронный или асинхронный?

A

setState - асинхронный. setState говорит React запустить следующую итерацию рендера. Однако React также может оптимизировать это процесс и несколько вызовов setState - приведут к одному рендеру.

46
Q

В чем разница memo и useMemo?

A

memo — это компонент высшего порядка.
Он нужен для повышения производительности и подходит для случаев, когда компонент рендерит одинаковый результат при одних и тех же значениях пропсов. В этом случае результат будет мемоизирован. Это значит, что React будет использовать результат последнего рендера, избегая повторного рендеринга.
При использовании memo пропсы по умолчанию сравниваются поверхностно. Можно передать свою функцию сравнения в качестве второго аргумента (если нужно контролировать сравнение).
useMemo - это хук, который возвращает мемоизированное значение функции, которая делает долгие вычисления. Эта оптимизация помогает избежать дорогостоящих вычислений при каждом рендере. useMemo будет повторно вычислять мемоизированное значение только тогда, когда значение какой-либо из зависимостей изменилось.

47
Q

Как реализовать сайд эффекты в Redux

A

Сайд эффект - это действие, которые должно произойти на диспатчинг экшена, помимо после сохранения в стор, например, логирование в консоль или отправка запроса на сервер.
Основной способ сделать сайд эффект - вызвать его в middleware. Можно написать свой middleware, а можно использовать сторонние библиотеки, например, redux thunk - для синхронных и простых асинхронных действий или redux saga - для сложных асинхронных действий.
Можно вызывать сайд эффекты в action сreator’ах. Однако, это не самый лучший способ, т.к. можно задиспатчить действие и без вызова action creator, тогда сайд эффект не сработает.

48
Q

React - реактивен?

A

Начнем с того, что React-компоненты это функции, которые мы не вызываем на прямую. Эти функции в некоторые моменты возвращают описание того что нужно рендерить.

Эти функции вызывает сам React в те самые “некоторые” моменты. И React может отложить этот вызов. React рекурсивно обходит дерево компонентов и может применять оптимизации - и задерживать рендеры чтобы избежать потерю кадров.

React в первую это UI фреймворк, и для того чтобы избежать тормозов такие меры оправданы. Т.к. данные могут поступать быстрее чем скорость обновления кадров - есть смысл объединять обновления в пакеты и обновлять пакетами.

Поэтому React это скорее «Планировщик», и реактивность не провалятся в React в чистом виде.

49
Q

Что такое синтетические события в React?

A

SyntheticEvent это обёртка над нативными событиями. SyntheticEvent является частью системы событий React.
Ваши обработчики событий получают экземпляр SyntheticEvent, это кроссбраузерная обёртка над нативным экземпляром события. У неё такой же интерфейс, как и у нативного события, включая методы stopPropagation() и preventDefault(). Эта обёртка помогает событиям работать одинаково во всех браузерах.
Еcли всё-таки нужно получить нативное браузерное событие, следует обратиться к атрибуту nativeEvent. Синтетические события отличаются от нативных событий браузера и непосредственно не связаны с ними.

50
Q

Разница между action и reducer

A

Action (действие) — это простые JavaScript объекты.
Они должны иметь тип, указывающий тип выполняемого действия.
По сути, действия — это некоторые данные, которые отправляются из вашего приложения в хранилище.
Редьюсер — это просто чистая функция, которая принимает предыдущее состояние и действие и возвращает обновленное состояние.

51
Q

Что такое store в Redux?

A

Store — это JavaScript объект, который содержит состояние приложения. Наряду с этим он также имеет следующие обязанности:
Разрешает доступ к состоянию через getState().
Позволяет обновлять состояние с помощью отправки действия dispatch(action).
Регистрирует слушателей через subscribe(listener).
Обрабатывает отмену регистрации слушателей с помощью функции, возвращаемой из subscribe(listener).

52
Q

Для чего используется Redux Thunk?

A

Redux Thunk — это промежуточное программное обеспечение (middleware), которое позволяет вам писать создателей действий (action creator), которые возвращают функцию вместо действия (action). Что такое action creators?
Затем thunk можно использовать для задержки отправки действия, если выполняется определенное условие. Это позволяет вам обрабатывать асинхронную диспетчеризацию действий.

53
Q

Что такое Middleware?

A

Middleware - это промежуточное программное обеспечение, которое используется для обработки запросов и реализации дополнительных функций или логики между отправкой запроса и получением ответа. В контексте Redux, middleware - это слой, который находится между вызовом action и изменением состояния в хранилище (store). Middleware позволяет перехватывать и обрабатывать действия, прежде чем они достигнут редуктора (reducer).

В Redux middleware действует как обработчик для action, который может применять манипуляции, запускать асинхронные операции, логировать действия, изменять состояние и многое другое. Он прозрачно интегрируется в процесс действий и может быть использован для различных целей, включая обработку сайд-эффектов, реализацию асинхронных операций, логирование, аутентификацию, маршрутизацию и других дополнительных функций.

Middleware в Redux принимает три аргумента: store (хранилище), next (следующий обработчик в цепочке middleware) и action (действие). Middleware может выполнить дополнительные задачи, после чего передать действие дальше в цепочку с помощью метода next(action). Каждый middleware может запускать свои собственные операции или модифицировать действие или состояние до передачи его следующему middleware или редуктору.

Примером middleware в Redux является Redux Thunk, Redux Saga, Redux Observable и другие, которые добавляют дополнительную функциональность и возможность обработки сайд-эффектов в приложении на основе Redux. Middleware в Redux позволяет создавать расширяемые и гибкие приложения, которые могут легко масштабироваться и взаимодействовать с внешними ресурсами или API.

54
Q

Напишите кастомный хук, который можно использовать для debounce’а ввода.

A

const useDebounce = (value, delay) => { const [debouncedValue, setDebouncedValue] = useState(value); // Создаем состояние для хранения "задержанного" значения // useEffect(() => { const timeout = setTimeout(() => { setDebouncedValue(value); // Обновляем "задержанное" значение после задержки }, delay); // // Очищаем таймаут при каждом изменении значения или при размонтировании компонента return () => { clearTimeout(timeout); }; }, [value]); // Перезапускаем эффект только при изменении значения // return debouncedValue; // Возвращаем "задержанное" значение }; // // Использование const Counter = () => { const [value, setValue] = useState(0); // Создаем состояние для хранения текущего значения const lastValue = useDebounce(value, 1000); // Используем наш кастомный хук useDebounce // return ( <div> <p> Current Value: {value} | Debounced Value: {lastValue} </p> <button onClick={() => setValue(value + 1)}>Increment</button> </div> ); };

55
Q

Напишите кастомный хук для копирования текста в буфер обмена.

A

function useCopyToClipboard(content) { const [isCopied, setIsCopied] = useState(false); // Создаем состояние для хранения информации об успешном/неуспешном копировании // const copy = useCallback(() => { navigator.clipboard // Используем API браузера для доступа к буферу обмена .writeText(content) // Копируем текст в буфер обмена .then(() => setIsCopied(true)) // Устанавливаем состояние в "скопировано" .then(() => setTimeout(() => setIsCopied(false), 1250)) // Через 1.25 секунды сбрасываем состояние в "не скопировано" .catch((err) => alert(err)); // Обрабатываем возможные ошибки }, [content]); // return [isCopied, copy]; // Возвращаем состояние и функцию для копирования } // // Использование export default function App() { const [isCopied, copy] = useCopyToClipboard("Text to copy!"); // Используем наш кастомный хук useCopyToClipboard // return <button onClick={copy}>{isCopied ? "Copied!" : "Copy"}</button>; // Отображаем кнопку "Copy" или "Copied!" в зависимости от состояния }

56
Q

Как использовать хук useId для создания уникальных идентификаторов?

A
  • useId не принимает никаких параметров.
  • useId возвращает уникальную строку идентификатора, связанную с этим конкретным вызовом useId в этом конкретном компоненте.

// Использование import { useId } from "react"; // const App = () => { const id = useId(); // return ( <form> <label htmlFor={email-${id}}>Email</label> <input type="text" id={email-${id}`} name=”email” />

  <label htmlFor={`password-${id}`}>Password</label>
  <input type="password" id={`password-${id}`} name="password" />
</form>   ); }; // // Плохая практика - не стоит использовать в качестве key const id = useId(); // return posts.map((post) => <article key={id}>...</article>);`
57
Q

Как проверить/валидировать пропсы в React?

A

Мы можем использовать пакет prop-types
Раньше, до React v15.5, это было частью самого React.

import PropTypes from "prop-types"; // function MyComponent({ name }) { return <div>Hello, {name}</div>; } // MyComponent.propTypes = { name: PropTypes.string, }; // export default MyComponent;

Еще один вариант - это добавить к проекту TypeScript.

58
Q

Приведите практический пример компонента высшего порядка в React.

A

// Компонент высшего порядка function WithLoading(Component) { return function WihLoadingComponent({ isLoading, ...props }) { if (!isLoading) return <Component {...props} />; return <p>Please wait, fetching your data in no time...</p>; }; } export default WithLoading;

59
Q

Чем полезен хук useDeferredValue?

A

useDeferredValue — это React хук, который позволяет вам отложить обновление части пользовательского интерфейса.
По сути, это позволяет вам выполнять технику debounce с меньшим количеством кода.
Подробный разбор хука useDeferredValue можно прочитать в статье Хуки useTransition и useDeferredValue в ReactJS 18.

// Использование import { useState, useDeferredValue } from "react"; // Компонент userList получает searchText для запроса списка пользователей import UserList from "./UserList.js"; // export default function App() { const [searchText, setSearchText] = useState(""); // отправить searchText по умолчанию const deferredQuery = useDeferredValue(searchText); // return ( <> <label> Search user: <input value={searchText} onChange={(e) => setSearchText(e.target.value)} /> </label> <div> <UserList searchText={deferredQuery} /> </div> </> ); }

60
Q

Как отследить клик за пределами компонента React?

A

export default function OutsideAlerter() { const clickMeDivRef = useRef(null); // useEffect(() => { const handleClickOutside = (event) => { if (!ref?.current?.contains(event.target)) { alert("You clicked outside of me!"); } }; // // Добавим прослушивание событий document.addEventListener("mousedown", handleClickOutside); // return () => { // Удалим прослушивание событий document.removeEventListener("mousedown", handleClickOutside); }; }, [clickMeDivRef]); // return <div ref={clickMeDivRef}>Clicked me?</div>; }

61
Q

Почему имена компонентов React должны начинаться с заглавных букв?

A

В JSX имена тегов нижнего регистра считаются тегами HTML. Однако имена тегов в нижнем регистре с точкой (аксессор свойства) не являются таковыми.

<person></person>

компилируется в React.createElement(‘person’) (тег html)
компилируется в React.createElement(Person)

<obj.person></obj.person>

компилируется в React.createElement(obj.person)

// Ошибка! Это компонент и должен начинаться с заглавной буквы function person(props) { // Верно! Это использование <div> верно, т.к. div это валидный элемент return <div>{props.isLearning ? "Great!" : "Hello!"}</div>; } // function App() { // Ошибка! React считает <person /> тэгом HTML, т.к. Не с заглавной буквы return <person isLearning={true} />; } // // Верно! Это компонент и должен начинаться с заглавной буквы function Person(props) { // Верно! Это использование <div> верно, т.к. div это валидный элемент return <div>{props.isLearning ? "Great!" : "Hello!"}</div>; } // function App() { // Верно! React знает, что <Person /> - это компонент, с заглавной буквы return <Person isLearning={true} />; }

62
Q

В чем разница между npx и npm?

A

npm — это менеджер пакетов, который можно использовать для установки пакетов node.js. npM - Manager.
npx— это инструмент для выполнения пакетов node.js. npX - Execute.
Неважно, установили ли вы этот пакет глобально или локально. npx временно установит его и запустит. npm также может запускать пакеты, если вы настроите файл package.json.
Поэтому, если вы хотите быстро проверить/запустить пакет без его установки - используйте npx.
create-react-app — это npm пакет, который должен запускаться только один раз в жизненном цикле проекта. Следовательно, предпочтительнее использовать npx для установки и запуска за один шаг.
> npx create-react-app my-app

63
Q

Как установить фокус на поле ввода после монтирования компонента в UI?

A

`import React, { useEffect, useRef } from “react”;
//
const SearchPage = () => {
const textInput = useRef(null);
//
useEffect(() => {
textInput.current.focus();
}, []);

return (
<div>
<input ref={textInput} type=”text” />
</div>
);
};`

64
Q

Что такое flushSync

A

Используется, чтобы заставить React сбросить всю ожидающую работу и синхронно обновить DOM.

import React, {useState} from "react" import {flushSync} from "react-dom" // const App = () => { const [count, setCount] = useState(0) const [count2, setCount2] = useState(0) // return ( <div className="App"> <button onClick={() => { // первое обновление flushSync(() => { setCount(count => count + 1) }) // второе обновление flushSync(() => { setCount2(count2 => count2 + 1) }) }}>click</ button > // <span>count: {count}</ span > <span>count2: {count2}</ span > </div> ) } // export default App

65
Q

Concurrent mode (Конкурентный режим)

A

Конкурентный режим — это не фича, а архитектура.
Это помогает приложениям оставаться отзывчивыми, подстраиваясь под производительность устройства пользователя и скорость сети, а также устраняет блокировку механизмов рендеринга, делая рендеринг прерываемым. В React несколько состояний могут быть обновлены одновременно.
Разница в том, чтобы синхронные непрерываемые обновления стали асинхронными прерываемыми обновлениями.
useDeferredValue и startTransition используются для обозначения несрочного обновления.

66
Q

Почему React компоненты не могут возвращать несколько элементов?

A
  • Компонент React в конце будет скомпилирован в функцию рендеринга, и возвращаемое значение функции может быть только одно. Если он не обернут в отдельный корневой узел, несколько значений будут возвращаться параллельно, что не допускается в JavaScript.

Виртуальный DOM React представляет собой древовидную структуру, и корневой узел дерева может быть только один. При наличии нескольких корневых узлов невозможно подтвердить, какое дерево нужно обновить.

67
Q

Как компоненты React могут возвращать несколько компонентов?

A
  • Используя HOC (Higher Order Functions)
  • Используя React.Fragment, вы можете добавить список элементов в группу, не создавая дополнительных узлов.
    -Используя массив
68
Q

Что такое React js

A

React JS - это внешняя библиотека JavaScript для создания веб-и мобильных пользовательских интерфейсов (TK).
Он был разработан Facebook в 2011 году.
React позволяет разработчикам создавать повторно используемые компоненты пользовательского интерфейса.
Его поддерживает большое сообщество с открытым исходным кодом.

69
Q

Что такое компоненты в Реакт?

A

Компоненты - это строительные материалы, которые React использует для создания пользовательского интерфейса веб-сайтов и приложений.
Компоненты разбивают пользовательский интерфейс на многоразовые части (одна из основных компетенций React). Затем React отображает каждый компонент пользовательского интерфейса по мере необходимости (отдельно от других), что является большой частью высокой производительности React.

70
Q

В твоем коде ошибка, как бы ты произвела отладку кода?

A
  1. Console.log
  2. DevTools в браузере
  3. React Developer Tools
  4. ESLint или TypeScript, чтобы выявлять потенциальные ошибки и проблемы в коде на ранних этапах разработки.
71
Q

Почему мы не должны обновлять состояние напрямую?

A

Если вы попытаетесь обновить состояние напрямую, он не будет повторно отображать компонент.

//Wrong this.state.message = 'Hello world'

Вместо этого используйте метод setState (). Он планирует обновление объекта состояния компонента. Когда состояние изменяется, компонент отвечает повторным рендерингом.

//Correct this.setState({ message: 'Hello World' })

Примечание. Вы можете напрямую назначить объекту состояния либо в конструкторе, либо с помощью последнего синтаксиса объявления поля класса javascript.

72
Q

Какова цель функции обратного вызова в качестве аргумента setState ()?

A

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

setState({ name: 'John' }, () => console.log('The name has updated and component re-rendered'))

73
Q

Что такое Lifting State Up в React?

A

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

74
Q

Если компоненту ничего не нужно отрисовывать, что мы можем сделать?

A

Метод render() или функциональный компонент может возвращать значение null.

75
Q

В чем особенность классовых компонентов в реакт?

A

Особенность классовых компонентов в React состоит в том, что они основаны на синтаксисе JavaScript классов. В классовых компонентах используется расширение класса React.Component и создается подкласс, который наследует функциональности React.Component.

Некоторые особенности классовых компонентов в React:

  1. Жизненный цикл: Классовые компоненты в React имеют набор методов жизненного цикла, таких как componentDidMount, componentDidUpdate и componentWillUnmount, которые позволяют выполнять определенные действия на определенных этапах жизненного цикла компонента.
  2. Внутреннее состояние: Классовые компоненты имеют возможность хранить внутреннее состояние (state) с помощью свойства state. Состояние может быть изменено с помощью метода setState, и изменения состояния обновят компонент.
  3. this: Внутри классовых компонентов, ключевое слово this относится к экземпляру класса компонента. Оно используется для доступа к состоянию, методам и другим свойствам компонента.
  4. Пропсы (props): Информация может быть передана классовому компоненту с помощью его свойства props, также как и в функциональных компонентах. Пропсы не могут быть изменены компонентом самостоятельно и должны быть переданы сверху, из родительского компонента.
76
Q

Кастомные хуки

A

Кастомные хуки - это функции, которые позволяют вам повторно использовать логику состояния и побочных эффектов между различными компонентами в React. Они используются в следующих случаях:

  1. Логика состояния и побочные эффекты: Когда у вас есть логика состояния или побочные эффекты, которые не укладываются в модель жизненного цикла компонентов (например, подписка на события, получение данных из API), вы можете создать кастомный хук для абстрагирования этой логики и повторного использования ее в разных компонентах.
  2. Загрузка и обработка данных: Кастомные хуки часто используются для упрощения работы с асинхронными операциями, такими как загрузка данных из API и их обработка. Как пример, вам может потребоваться создать кастомный хук для управления состоянием загрузки, обработки ошибок и результатом получения данных.
  3. Абстрагирование логики форм: Кастомные хуки могут быть полезны для абстрагирования логики управления формами, валидации ввода и обработки отправки формы. Это позволяет повторно использовать эту логику в разных компонентах, делая код более модульным и читабельным.

Примеры кастомных хуков:
1. useFetch: Кастомный хук для упрощения загрузки данных из API.
2. useLocalStorage: Кастомный хук для управления состоянием локального хранилища браузера.
3. useForm: Кастомный хук для управления состоянием формы и ее валидацией.

77
Q

Какие данные лучше хранить в состоянии компонента, а какие передавать через пропсы? Приведите пример.

A

Когда выбирается, какие данные следует хранить в состоянии компонента, а какие следует передавать через пропсы, обычно руководствуются следующими рекомендациями:

  1. Состояние компонента: Данные, которые изменяются внутри самого компонента и влияют только на его локальное состояние, могут храниться в его состоянии. Примером может быть значение формы, отображение или скрытие компонентов, текущий режим работы и т.д.
  2. Пропсы: Данные, которые должны быть доступны и передаваться из родительского компонента, следует хранить в пропсах и передавать через компоненты-потомки. Примером может быть данные из внешнего источника, состояние вышестоящего компонента, отображение списка и т.д.
78
Q

Почему библиотека React быстрая? Что такое Virtual DOM и Shadow DOM?

A

Библиотека React считается быстрой из-за оптимизированного подхода к работе с Virtual DOM (виртуальным DOM) и его эффективной синхронизацией с реальным DOM.

Virtual DOM - это концепция, при которой React создает виртуальное представление DOM-структуры приложения в памяти. Когда компоненты обновляются, React сравнивает виртуальное представление с реальным DOM и распознает минимальное количество изменений, которые необходимо внести, чтобы изменить внешний вид и состояние приложения. Затем он применяет эти изменения только к соответствующим узлам реального DOM, минимизируя количество ненужных операций повторного рендеринга.

Этот подход с использованием Virtual DOM позволяет React обновлять только те части веб-страницы, которые действительно изменились, вместо полного обновления всего дерева DOM. Это значительно увеличивает производительность и позволяет более эффективно обрабатывать изменения в больших и сложных приложениях.

Shadow DOM (теневой DOM) - это другая технология, связанная с веб-компонентами и нативным веб-средой. Shadow DOM предлагает область для ограничения стилизации и управления отображением элементов, чтобы они не конфликтовали с элементами внешнего контекста веб-страницы. Он позволяет создавать изолированные компоненты с их собственными стилями и поведением. Shadow DOM позволяет изолированно создавать и стилизовать компоненты, но он находится на нижнем уровне, отличается от Virtual DOM и используется в разных контекстах.

79
Q

React - это библиотека или фреймворк? Какая разница между этими двумя понятиями.

A

React - это библиотека, а не фреймворк. Разница между библиотекой и фреймворком состоит в уровне контроля и гибкости, которые они предоставляют разработчику при разработке приложений.

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

Фреймворк (framework), с другой стороны, является более всеобъемлющим. Он устанавливает определенную структуру и правила разработки, определяет архитектуру и предоставляет больше контроля над процессом разработки. Фреймворк предоставляет больше готовых решений и навязывает определенные принципы и методологии разработки. Он имеет более жесткую структуру и контролирует основные аспекты приложения.

80
Q

Расскажи про основные библиотеки React, которые ты знаешь. Какие у них плюсы и минусы?

A
  1. React Router: Позволяет реализовать маршрутизацию в клиентских приложениях React. Она позволяет создавать ссылки, переключать компоненты в зависимости от URL, предоставляет API для работы с историей браузера и многое другое. Одним из основных преимуществ React Router является его удобный и мощный API для настройки маршрутов приложения.
  2. Redux: Предоставляет управление состоянием приложения. Он помогает организовать и контролировать данные приложения и обеспечивает однонаправленный поток данных. Redux значительно упрощает отслеживание и изменение состояния приложения, а также улучшает управление состоянием в приложениях с большим количеством компонентов. Однако, из-за своей сложности Redux может быть избыточным для небольших проектов.
  3. Axios: Библиотека для выполнения HTTP-запросов из JavaScript-приложений. Она упрощает обработку запросов и ответов, обеспечивает легко настраиваемый интерфейс и позволяет легко работать с промисами для обработки асинхронных операций. Одним из наиболее значимых преимуществ Axios является его простота использования и большое количество дополнительных функций.
  4. Material-UI: Библиотека компонентов, реализующая дизайн в стиле Material Design от Google. Она предоставляет готовые компоненты, которые можно использовать для создания модернизированного и красивого пользовательского интерфейса. Material-UI предлагает большую гибкость, адаптивность и возможность кастомизации, но иногда может быть избыточным для простых проектов.
81
Q

Расскажи про хук useMemo - когда его надо использовать, в чем его особенности, как написать его полифил?

A

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

const myCalculation = useMemo(()=> {
return current+”test”
},[current])

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

Полифил:

82
Q

Расскажи про хук useCallback - когда его надо использовать, в чем его особенности?

A

Это синтаксический сахар над useMemo:
const myUseCallback = useMemo(()=> {
return () => {}
},[])

Пример:
const handleClick = useCallback(() => {
setCount(count + 1);
}, [count, setCount]);

83
Q
A