Сложные вопросы на собеседовании по React
месяц назад·3 мин. на чтение
В данной статье рассматриваются сложные вопросы, которые могут быть заданы на собеседовании по React. Вопросы охватывают широкий спектр тем.
Собеседование по React может быть довольно сложным, так как это одна из наиболее популярных и требующих навыков библиотек по разработке веб-приложений. В этой статье мы рассмотрим несколько сложных вопросов и ответов на собеседовании по React, которые могут помочь вам подготовиться и успешно пройти такое интервью.
1. Что такое React и какие принципы лежат в его основе?
React – это JavaScript-библиотека, разработанная Facebook, которая используется для создания пользовательских интерфейсов. Одной из главных особенностей React является использование виртуального DOM (Virtual DOM), который при значительном изменении состояния компонента или данных эффективно обновляет только необходимые элементы интерфейса. React также основан на принципе однонаправленного потока данных, где данные передаются от верхнего родительского компонента к дочерним.2. В чем разница между компонентами классов и функциональными компонентами?
Классовые компоненты являются старым подходом к созданию компонентов в React и используются для создания сложных компонентов, которые имеют внутреннее состояние и методы жизненного цикла. Функциональные компоненты – это новый подход, появившийся с появлением React Hooks, который позволяет создавать компоненты в виде функций. Такие компоненты проще и более читабельны, но не имеют встроенной поддержки состояния и методов жизненного цикла. Однако с помощью хуков можно добавить их в функциональные компоненты.3. Что такое контекст (context) в React и для чего он используется?
Контекст – это механизм, предоставляемый React, который позволяет передавать данные через иерархию компонентов без явной передачи пропсов по каждому уровню. Контекст особенно полезен, когда некоторые данные должны быть доступны во многих компонентах на разных уровнях иерархии. Он также позволяет избежать "прокидывания" пропсов через несколько слоев компонентов.4. Что такое React Hooks и для чего они используются?
React Hooks представляют собой новое API, добавленное в React версии 16.8, которое позволяет использовать состояние и другие функциональности React в функциональных компонентах. Они позволяют избежать использования классовых компонентов и добавляют возможности, такие как использование состояния (useState
), эффектов (useEffect
) и контекста (useContext
). Они упрощают разработку и делают код компонентов более чистым и читабельным.
5. Что такое виртуальный DOM (Virtual DOM) в React и как он работает?
Виртуальный DOM – это внутренняя структура данных, используемая React, которая представляет набор элементов интерфейса в виде JS-объектов. Когда состояние компонента или данные изменяются, React создает новую виртуальную DOM-структуру и сравнивает ее с предыдущей. Затем React определяет разницу между новым и старым состоянием и эффективно обновляет только изменившиеся элементы на странице реального DOM. Это позволяет значительно увеличить производительность при рендеринге больших и сложных интерфейсов.6. Как происходит передача данных между компонентами в React?
В React данные между компонентами передаются через пропсы (props). Пропсы – это параметры, передаваемые в компонент при его использовании. Они позволяют передавать данные от родительского компонента к дочернему, а также вызывать функции из родительского компонента в дочернем. Для передачи данных вниз по иерархии компонентов используется подход "однонаправленного потока данных".7. Каким образом можно оптимизировать производительность компонентов в React?
Оптимизация производительности компонентов в React может выполняться с помощью следующих методов:- Мемоизация компонентов с помощью
- PureComponent или React.memo
- Использование ключей (keys) в списках элементов
- Ленивая загрузка компонентов (React.lazy)
- Пакетная обработка (батчинг)
- Оптимизация работы с внешними источниками данных (например, работа с API)
- Использование shouldComponentUpdate или PureComponent для предотвращения ненужных ререндеров
- Оптимизация избыточного рендеринга (например, с помощью
useEffect
)
Как передать пропсы React компоненту
2 года назад·5 мин. на чтение
Компоненты React используют пропсы (props) для связи друг с другом. Каждый родительский компонент может передавать некоторую информацию своим дочерним компонентам, предоставляя им пропсы. Пропсы могут напоминать атрибуты HTML, но вы можете передавать через них любое значение JavaScript, включая объекты, массивы и функции.
Содержание туториала по React
Компоненты React используют пропсы (props) для связи друг с другом. Каждый родительский компонент может передавать некоторую информацию своим дочерним компонентам, предоставляя им пропсы. Пропсы могут напоминать атрибуты HTML, но вы можете передавать через них любое значение JavaScript, включая объекты, массивы и функции.
Пропсы позволяют вам думать о родительских и дочерних компонентах независимо друг от друга. Например, вы можете изменить пропсы
Известные пропсы
Пропсы — это информация, которую вы передаете тегу JSX. Например,className
, src
, alt
, width
и height
— вот некоторые пропсы, которые вы можете передать <img>
:
Пропсы, которые вы можете передать тегуfunction Avatar() { return ( <img className="avatar" src="https://example.com/userpic.jpg" alt="Userpic" width={100} height={100} /> ); } export default function Profile() { return <Avatar />; }
<img>
, предопределены (ReactDOM соответствует стандартам HTML). Но вы можете передать любые пропсы своим собственным компонентам, таким как <Avatar>
, чтобы настроить их.
Передача пропсов в компонент
В этом коде компонентProfile
не передает никаких пропсов своему дочернему компоненту Avatar
:
Вы можете передать вexport default function Profile() { return <Avatar />; }
Avatar
некоторые пропсы в два этапа.
Шаг 1: Передайте пропсы дочернему компоненту
Во-первых, передайте некоторые пропсы вAvatar
. Например, давайте передадим два пропса: person
(объект) и size
(число):
Если двойные фигурные скобки послеexport default function Profile() { return ( <Avatar person={{ name: 'User Name 1', imageId: '12345' }} size={100} /> ); }
person=
вас смущают, помните, что они являются просто объектом внутри фигурных скобок JSX.
Теперь вы можете прочитать эти пропсы внутри компонента Avatar
.
Шаг 2: Прочтите пропсы внутри дочернего компонента
Вы можете прочитать эти пропсы, указав их имена -person
, size
- разделенные запятыми внутри ({
и })
непосредственно после function Avatar
. Это позволяет использовать их внутри кода Avatar
, как если бы вы использовали переменную.
Добавьте немного логики вfunction Avatar({ person, size }) { // person и size можно здесь использовть }
Avatar
, которая использует пропсы person
, size
в отображении, и все готово.
Теперь вы можете настроить Avatar
для отображения разными способами с разными пропсы.
// utils.js export function getImageUrl(person, size = 's') { return 'https://example.com/' + person.imageId + size + '.jpg'; }
// App.js import { getImageUrl } from './utils.js'; function Avatar({ person, size }) { return ( <img className="avatar" src={getImageUrl(person)} alt={person.name} width={size} height={size} /> ); } export default function Profile() { return ( <div> <Avatar size={100} person={{ name: 'User Name 1', imageId: '12345', }} /> <Avatar size={80} person={{ name: 'User Name 2', imageId: '12346', }} /> <Avatar size={50} person={{ name: 'User Name 3', imageId: '12347', }} /> </div> ); }
person
или size
внутри Profile
, не задумываясь о том, как Avatar
их использует. Точно так же вы можете изменить то, как Avatar
использует эти пропсы, не заглядывая в Profile
.
Вы можете думать о пропсах как о «ручках», которые вы можете регулировать. Они выполняют ту же роль, что и аргументы для функций — на самом деле пропсы являются единственным аргументом для вашего компонента. Функции компонента React принимают один аргумент, объект props
:
Обычно вам не нужен весь объект пропса, поэтому можно разбить его на отдельные пропсы. Не пропустите пару фигурных скобокfunction Avatar(props) { let person = props.person; let size = props.size; // ... }
{
и }
внутри (
и )
при объявлении пропсов:
Этот синтаксис называется «деструктурированием» и эквивалентен чтению свойств из параметра функции:function Avatar({ person, size }) { // ... }
function Avatar(props) { let person = props.person; let size = props.size; // ... }
Как указать значения по умолчанию для пропса
Если вы хотите присвоить пропсу значение по умолчанию, чтобы использовать его, когда значение не указано, вы можете сделать это с помощью деструктуризации, поставив=
и значение по умолчанию сразу после параметра:
Теперь, если вfunction Avatar({ person, size = 100 }) { // ... }
<Avatar person={...} />
передан пропс size
, размер будет установлен на 100
.
Значение по умолчанию используется только в том случае, если параметр size
отсутствует или если вы передаете size={undefined}
. Но если вы передадите size={null}
или size={0}
, значение по умолчанию не будет использоваться.
Перенаправление пропсов с синтаксисом распыления JSX
Иногда отправка пропсов повторяется:В повторяющемся коде нет ничего плохого. Но иногда хочется сделать код короче. Некоторые компоненты передают все свои пропсы своим дочерним компонентам, например, какfunction Profile({ person, size, isSepia, thickBorder }) { return ( <div className="card"> <Avatar person={person} size={size} isSepia={isSepia} thickBorder={thickBorder} /> </div> ); }
Profile
делает с Avatar
. Поскольку они не используют никакие свои пропсы напрямую, может иметь смысл использовать более краткий синтаксис распыления (spread):
Это пример перенаправления всех пропсовfunction Profile(props) { return ( <div className="card"> <Avatar {...props} /> </div> ); }
Profile
в Avatar
без перечисления каждого из их имен.
Используйте расширенный синтаксис с ограничениями. Если вы используете его в каждом компоненте - значит что-то не так. Часто это указывает на то, что следует разделить компоненты и передать дочерние компоненты как JSX. Подробнее об этом далее.
Передача JSX в качестве дочернего компонента
Обычно встроенные теги браузера вкладывают друг в друга:Иногда вы захотите вложить свои собственные компоненты таким же образом:<div> <img /> </div>
Когда вы вкладываете контент в тег JSX, родительский компонент получит этот контент в просе, называемом<Card> <Avatar /> </Card>
children
. Например, компонент Card
ниже получит проп children
, который является <Avatar />
, и отобразит его в обертке div
:
// App.js import Avatar from './Avatar.js'; function Card({ children }) { return <div className="card">{children}</div>; } export default function Profile() { return ( <Card> <Avatar size={100} person={{ name: 'User Name', imageId: '12345', }} /> </Card> ); }
// Avatar.jsx import { getImageUrl } from './utils.js'; export default function Avatar({ person, size }) { return ( <img className="avatar" src={getImageUrl(person)} alt={person.name} width={size} height={size} /> ); }
Вы можете думать о компоненте с пропсом// utils.js export function getImageUrl(person, size = 's') { return 'https://example.com/' + person.imageId + size + '.jpg'; }
children
как о специальной лозейке, которую можно «заполнить» родительскими компонентами с произвольным JSX. Вы часто будете использовать проп children
для визуальных оболочек: панелей, сеток и т.д.
Как пропсы меняются со временем
КомпонентClock
ниже получает два пропса от своего родительского компонента: color
и time
. (Код родительского компонента опущен, поскольку он использует состояние, в которое мы пока не будем углубляться.)
Этот пример иллюстрирует, что компонент может получать пропсы с течением времени. Проп не всегда статичен. Здесь пропexport default function Clock({ color, time }) { return <h1 style={{ color: color }}>{time}</h1>; }
time
меняется каждую секунду, а проп color
меняется, когда вы выбираете другой цвет. Пропсы отражают данные компонента в любой момент времени, а не только в начале.
Пропсы иммутабельны — термин из информатики, означающий «неизменяемый». Когда компоненту необходимо изменить свои пропсы (например, в ответ на взаимодействие с пользователем или новые данные), ему придется «попросить» родительский компонент передать ему другие пропсы — новый объект. Затем его старые пропсы будут отброшены, и в конечном итоге движок JavaScript очистит занятую ими память.
Не пытайтесь "изменить пропсы" напрямую. Когда вам нужно отреагировать на пользовательский ввод (например, изменить выбранный цвет), вам нужно будет "установить состояние", о котором вы можете узнать в разделе "Состояние - память компонента".
Резюме
- Чтобы передать пропсы, добавьте их в JSX, как и в случае с атрибутами HTML.
- Чтобы прочитать пропсы, используйте синтаксис деструктурирования
function Avatar({ person, size })
. - Вы можете указать значение по умолчанию, например
size = 100
, которое используется для отсутствующих и неопределенных пропсов. - Вы можете перенаправить все пропсы с помощью синтаксиса распыления JSX
<Avatar {...props} />
, но не злоупотребляйте им. - Вложенный JSX, такой как
<Card><Avatar /></Card>
, будет отображаться как пропchildren
компонентаCard
. - Пропсы - доступны только для чтения. Это такой снимок компонента во времени: каждый рендер получает новую версию пропса.
- Нельзя менять пропсы внутри компонента. Когда вам нужна интерактивность, вам нужно установить состояние.