В этой статье представлен список вопросов, которые могут быть заданы на собеседовании для фронтенд-разработчика с опытом работы с React.
Когда дело доходит до собеседования на должность React фронтенд-разработчика, очень важно быть хорошо подготовленным к техническим вопросам. React стал одной из самых популярных библиотек JavaScript для создания пользовательских интерфейсов, и работодатели часто сосредотачиваются на оценке понимания кандидатом основных концепций, лучших практик и связанных с ними технологий. В этой статье мы рассмотрим полный список вопросов, которые часто задают во время собеседований с фронтенд-разработчиками React. Ознакомившись с этими вопросами и ответами на них, вы сможете повысить свои шансы на успех и продемонстрировать свое мастерство в разработке React. Итак, давайте углубимся и изучим ключевые темы на собеседовании с React Frontend Developer.
7. Каковы особенности использования
8. В чем особенности использования
Хук
23. Для чего используется
24. Для чего используется
25. В чем разница между
27. Для чего используется
В типичном React-приложении данные передаются сверху вниз (от родительского компонента к дочернему) с помощью входных параметров. Однако такой способ использования может оказаться слишком громоздким для некоторых видов пропсов (например, выбранный язык, тема пользовательского интерфейса), которые должны быть переданы многим компонентам в приложении. Контекст предоставляет способ обмена такими данными между компонентами без необходимости явной передачи входных параметров через
каждый уровень дерева.
Компонент, вызывающий 28. Для чего используется
29. Что такое
32. Зачем нужны ключи в списках при использовании
Ключи помогают React определить, какие элементы были изменены, добавлены или удалены. Они должны быть указаны так, чтобы React мог сопоставить элементы массива с течением времени. Лучший способ выбрать ключ — использовать строку, которая будет четко отличать элемент списка от его соседей. Чаще всего в качестве ключей вы будете использовать идентификаторы из ваших данных.
1. Какие хуки React вы знаете?
useState
: используется для управления состоянием в функциональных компонентах.useEffect
: используется для выполнения побочных эффектов в функциональных компонентах, таких как получение данных или подписка на события.useContext
: используется для доступа к значению контекста React в функциональном компоненте.useRef
: Используется для создания изменяемых ссылок на элементы или значения, которые сохраняются между рендерами.useCallback
: Используется для мемоизации функций, чтобы предотвратить ненужные повторные рендеры.useMemo
: используется для мемоизации значений с целью повышения производительности за счет кэширования ресурсоемких вычислений.useReducer
: Используется для управления состоянием с помощью функции редьюсера, аналогично тому, как работает Redux.useLayoutEffect
: похож наuseEffect
, но эффект выполняется синхронно после всех мутаций DOM.useId
useTransition и useDeferredValue
2. Что такое Virtual DOM?
Virtual DOM — это концепция в React, при которой создается и хранится в памяти легковесное виртуальное представление фактического DOM (Document Object Model). Это метод программирования, используемый для оптимизации производительности веб-приложений. Когда вносятся изменения в данные или состояние компонента React, виртуальный DOM обновляется вместо того, чтобы напрямую манипулировать реальным DOM. Затем виртуальный DOM вычисляет разницу между предыдущим и обновленным состоянием компонента. Этот процесс известен под названием сравнения (diffing). После того, как различия выявлены, React эффективно обновляет только необходимые части реального DOM, чтобы отразить изменения. Такой подход минимизирует количество фактических манипуляций с DOM и повышает общую производительность приложения. Используя виртуальный DOM, React предоставляет способ создания динамических и интерактивных пользовательских интерфейсов, обеспечивая при этом оптимальную эффективность и скорость рендеринга.3. Как отобразить массив элементов?
Чтобы отобразить массив элементов, вы можете использовать методmap()
для итерации по массиву и возврата нового массива элементов React.
const languages = [ "JavaScript", "TypeScript", "Python", ]; function App() { return ( <div> <ul>{languages.map((language) => <li>{language}</li>)}</ul> </div> ); }
4. В чем разница между контролируемыми и неконтролируемыми компонентами?
Разница между контролируемыми (управляемыми) и неконтролируемыми компонентами заключается в том, как они управляют своим состоянием и обновляют его. Управляемые компоненты — это компоненты, состояние которых контролируется React. Компонент получает свое текущее значение и обновляет его через входные параметры. Он также запускает функцию обратного вызова при изменении значения. Это означает, что компонент не хранит собственное внутреннее состояние. Вместо этого родительский компонент управляет и передает значение управляемому компоненту.Неконтролируемые компоненты, с другой стороны, управляют своим состоянием внутренне с помощью ссылок или других методов. Они хранят и обновляют свое состояние независимо, не полагаясь на входные параметры или обратные вызовы. Родительский компонент имеет меньший контроль над состоянием неконтролируемых компонентов.import { useState } from 'react'; function App() { const [value, setValue] = useState(''); return ( <div> <h3>Controlled Component</h3> <input name="name" value={name} onChange={(e) => setValue(e.target.value)} /> <button onClick={() => console.log(value)}>Get Value</button> </div> ); }
import { useRef } from 'react'; function App() { const inputRef = useRef(null); return ( <div className="App"> <h3>Uncontrolled Component</h3> <input type="text" name="name" ref={inputRef} /> <button onClick={() => console.log(inputRef.current.value)}>Get Value</button> </div> ); }
5. В чем разница между компонентами React на основе классов и функциональными компонентами React?
Основное различие между компонентами, основанными на классах, и функциональными компонентами заключается в том, как они определены и синтаксис, который они используют. Компоненты, основанные на классах, определяются как ES6 классы и расширяют классReact.Component
. Они используют метод render
для возврата JSX, который определяет выходные данные компонента. Компоненты класса имеют доступ к методам жизненного цикла компонентов и управлению состоянием через this.state
и this.setState()
.
Функциональные компоненты, с другой стороны, определяются как простые функции JavaScript. Они принимают входные параметры в качестве аргументов и возвращают JSX напрямую. Функциональные компоненты не имеют доступа к методам жизненного цикла или состоянию. Однако с введением React Hooks в React 16.8 функциональные компоненты теперь могут управлять состоянием и использовать другие функции, такие как контекст и эффекты.class App extends React.Component { state = { value: 0, }; handleAgeChange = () => { this.setState({ value: this.state.value + 1 }); }; render() { return ( <> <p>Value is {this.state.value}</p> <button onClick={this.handleAgeChange}> Increment value </button> </> ); } }
В целом, функциональные компоненты считаются более простыми и удобными для чтения и тестирования. Рекомендуется использовать функциональные компоненты везде, где это возможно, если нет особой необходимости в компонентах, основанных на классах.import { useState } from 'react'; const App = () => { const [value, setValue] = useState(0); const handleAgeChange = () => { setValue(value + 1); }; return ( <> <p>Value is {value}</p> <button onClick={handleAgeChange}> Increment value </button> </> ); }
6. Каковы методы жизненного цикла компонента?
Методы жизненного цикла — это способ подключения к различным этапам жизненного цикла компонента, что позволяет выполнять определенный код в определенное время. Жизненный цикл компонента легче понять через классовые компоненты. Вот список основных методов жизненного цикла:constructor
: Это первый метод, вызываемый при создании компонента. Он используется для инициализации обработчиков событий состояния и привязки. В функциональных компонентах для аналогичных целей можно использовать хукuseState
.render
: Этот метод отвечает за рендеринг JSX-разметки и возвращает контент, который будет отображаться на экране.componentDidMount
: этот метод вызывается сразу после рендеринга компонента в DOM. Он обычно используется для задач инициализации, таких как вызовы API или настройка прослушивателей событий.componentDidUpdate
: Этот метод вызывается при изменении входных параметров или состояния компонента. Он позволяет выполнять побочные эффекты, обновлять компонент на основе изменений или запускать дополнительные вызовы API.componentWillUnmount
: Этот метод вызывается непосредственно перед удалением компонента из DOM. Он используется для очистки любых ресурсов, которые были настроены вcomponentDidMount
, таких как удаление прослушивателей событий или отмена таймеров.
componentWillMount
, componentWillReceiveProps
и componentWillMount
, componentWillUpdate
устарели или заменены альтернативными методами или хуками.
Что касается this
, то оно относится к текущему экземпляру компонента класса. Он позволяет получить доступ к свойствам и методам внутри компонента. В функциональных компонентах this
не используется, так как функции не привязаны к конкретному экземпляру.
7. Каковы особенности использования useState
?
useState
возвращает значение состояния и функцию для его обновления.
Во время первоначальной визуализации возвращаемое состояние соответствует значению, переданному в качестве первого аргумента. Функцияconst [value, setValue] = useState('Some state');
setState
используется для обновления состояния. Он принимает новое значение состояния в качестве параметра и ставит в очередь повторный рендеринг компонента. Функция setState
также может принимать функцию обратного вызова в качестве параметра, которая принимает в качестве параметра предыдущее значение состояния.
8. В чем особенности использования useEffect
?
Хук useEffect
позволяет выполнять побочные эффекты в функциональном компоненте.
Мутации, подписки, таймеры, логирование и другие побочные эффекты не допускаются внутри основного тела функционального компонента, известного как фаза рендеринга React. Это может привести к запутанным ошибкам и несоответствиям в пользовательском интерфейсе.
Вместо этого рекомендуется использовать useEffect
. Функция, переданная в useEffect
, будет выполнена после того, как рендер будет зафиксирован на экране, или, если вы передадите массив зависимостей в качестве второго параметра, функция будет вызываться каждый раз, когда одна из зависимостей изменяется.
useEffect(() => { console.log('Logging something'); }, [])
9. Как отследить размонтирование функционального компонента?
useEffect
создает ресурсы, которые необходимо очистить или сбросить, прежде чем компонент уничтожится, такие как подписка или идентификатор таймера.
Для этого функция, переданная useEffect
, может возвращать функцию очистки. Функция очистки запускается перед удалением компонента из пользовательского интерфейса для предотвращения утечек памяти. Кроме того, если компонент визуализируется несколько раз (как это обычно бывает), предыдущий эффект очищается перед выполнением следующего.
useEffect(() => { function handleChange(value) { setValue(value); } SomeAPI.doFunction(id, handleChange); return function cleanup() { SomeAPI.undoFunction(id, handleChange); }; })
10. Что такое пропсы в React?
Пропсы - это данные, которые передаются компоненту из родителя. Пропсы доступны только для чтения и не могут быть изменены.// Parent component const Parent = () => { const data = "Hello, World!"; return ( <div> <Child data={data} /> </div> ); }; // Child component const Child = ({ data }) => { return <div>{data}</div>; };
11. Что такое менеджер состояния и с какими вы работали?
Менеджер состояния — это инструмент или библиотека, которая помогает управлять состоянием приложения. Он предоставляет централизованное хранилище или контейнер для хранения и управления данными, к которым могут обращаться и обновлять различные компоненты приложения. Менеджер состояний решает несколько задач. Во-первых, хорошей практикой является отделение данных и связанной с ними логики от компонентов. Во-вторых, при использовании локального состояния и передаче его между компонентами код может стать запутанным из-за возможности глубокой вложенности компонентов. Имея глобальное хранилище, мы можем получать доступ к данным из любого компонента и изменять их. Наряду с React Context, в качестве библиотек управления состоянием обычно используются Redux или MobX.12. В каких случаях можно использовать локальное состояние, а когда — глобальное?
Локальное состояние рекомендуется использовать в тех случаях, когда оно используется только в рамках одного компонента и нет планов передавать его в другие компоненты. Локальное состояние также используется в компоненте, представляющем отдельный элемент в списке. Однако, если декомпозиция компонентов включает вложенные компоненты с данными, передаваемыми вниз по иерархии, лучше использовать глобальное состояние.13. Что такое редьюсер в Redux?
Редьюсер — это чистая функция, которая принимает состояние и действие (action) в качестве параметров. Внутри редьюсера мы отслеживаем тип полученного действия и в зависимости от него модифицируем состояние и возвращаем новый объект состояния.export default function appReducer(state = initialState, action) { // The reducer normally looks at the action type field to decide what happens switch (action.type) { // Do something here based on the different types of actions default: // If this reducer doesn't recognize the action type, or doesn't // care about this specific action, return the existing state unchanged return state } }
14. Что такое действие (action) и как изменить состояние в Redux?
Action — это простой объект JavaScript, который должен иметь поле с тип.При необходимости можно также добавить некоторые данные в качестве полезных данных (payload). Для того, чтобы изменить состояние, необходимо вызвать функцию dispatch , в которую мы передаем действие{ type: "SOME_TYPE" }
{ type: "SOME_TYPE", payload: "Any payload", }
15. Какой паттерн реализует Redux?
Redux реализует шаблон Flux, который представляет собой шаблон управления предсказуемым состоянием для приложений. Он помогает в управлении состоянием приложения, предоставляя однонаправленный поток данных и централизованное хранилище состояния приложения.16. Какой паттерн реализует Mobx?
Mobx реализует шаблон Observer, также известный как шаблон Publish-Subscribe.17. В чем особенности работы с Mobx?
Mobx предоставляет декораторы, такие какobservable
и computed
для определения наблюдаемого состояния и реактивных функций. Действия, помеченные действием, используются для изменения состояния, гарантируя, что все изменения отслеживаются. Mobx также предлагает автоматическое отслеживание зависимостей, различные типы реакций, точный контроль над реактивностью и бесшовную интеграцию с React через пакет mobx-react
. В целом, Mobx упрощает управление состоянием, автоматизируя процесс обновления на основе изменений в наблюдаемом состоянии.
18. Как получить доступ к переменной в состоянии Mobx?
Вы можете получить доступ к переменной в состоянии с помощью декоратора, чтобы определить переменную какobservable
. Вот пример:
В этом примереimport { observable, computed } from 'mobx'; class MyStore { @observable myVariable = 'Hello Mobx'; @computed get capitalizedVariable() { return this.myVariable.toUpperCase(); } } const store = new MyStore(); console.log(store.capitalizedVariable); // Output: HELLO MOBX store.myVariable = 'Hi Mobx'; console.log(store.capitalizedVariable); // Output: HI MOBX
myVariable
определена как наблюдаемая с помощью декоратора observable
. Затем вы можете получить доступ к переменной с помощью store.myVariable
. Любые изменения, внесенные в myVariable
, автоматически запускают обновления в зависимых компонентах или реакциях.
19. В чем разница между Redux и Mobx?
Redux — это более простая библиотека управления состоянием, которая следует строгому однонаправленному потоку данных и обеспечивает неизменяемость. Он требует больше шаблонного кода и явных обновлений, но имеет отличную интеграцию с React. Mobx, с другой стороны, предоставляет более гибкий и интуитивно понятный API с меньшим количеством шаблонного кода. Он позволяет напрямую изменять состояние и автоматически отслеживать изменения для повышения производительности. Выбор между Redux и Mobx зависит от ваших конкретных потребностей и предпочтений.20. Что такое JSX?
По умолчанию для создания элементов в react используется следующий синтаксис.Но мы привыкли видеть это именно такconst someElement = React.createElement( 'h3', {className: 'title__value'}, 'Some Title Value' );
Это именно то, что называется jsx. Это своего рода расширение языка, что упрощает восприятие кода и разработку.const someElement = ( <h3 className='title__value'>Some Title Value</h3> );
21. Что такое prop drilling?
Зrop drilling относится к процессу прохождения пропсов параметров через несколько уровней вложенных компонентов, даже если некоторые промежуточные компоненты не используют эти входные параметры напрямую. Это может привести к сложной и громоздкой структуре кода.В этом примере проп// Parent component const Parent = () => { const data = "Hello, World!"; return ( <div> <ChildA data={data} /> </div> ); }; // Intermediate ChildA component const ChildA = ({ data }) => { return ( <div> <ChildB data={data} /> </div> ); }; // Leaf ChildB component const ChildB = ({ data }) => { return <div>{data}</div>; };
data
передается из компонента Parent
в ChildA
, а затем из ChildA
в ChildB
, даже если ChildA
не использует проп напрямую. Это может стать проблемой при наличии множества уровней вложенности или когда доступ к данным должен осуществляться компонентами, находящимися ниже по дереву компонентов. Это может усложнить поддержку и понимание кода.
Проп дриллинг можно смягчить, используя другие шаблоны, такие как библиотеки управления контекстом или состоянием, такие как Redux или MobX. Эти подходы позволяют компонентам получать доступ к данным без необходимости передачи входных параметров через каждый промежуточный компонент.
22. Как отобразить элемент по условию?
Можно использовать любые условные операторы, в том числе тернарные.return ( <div> {isVisible && <span>I'm visible!</span>} </div> ); return ( <div> {isOnline ? <span>I'm online!</span> : <span>I'm offline</span>} </div> ); if (isOnline) { element = <span>I'm online!</span>; } else { element = <span>I'm offline</span>; } return ( <div> {element} </div> );
23. Для чего используется useMemo
и как он работает?
useMemo
используется для кэширования и запоминания результат расчетов.
Передайте создающую функцию и массив зависимостей. useMemo
будет пересчитывать мемоизированное значение только в том случае, если значение какой-либо из зависимостей изменилось. Такая оптимизация помогает избежать дорогостоящих вычислении при каждом рендеринге.
Первым параметром передается функция обратного вызова, в которой выполняются вычисления, а вторым - массив зависимостей. Функция будет повторно выполнять вычисления только при изменении хотя бы одной из зависимостей.
const memoValue = useMemo(() => computeFunc(paramA, paramB), [paramA, paramB]);
24. Для чего используется useCallback
и как он работает?
useCallback
вернет мемоизированную версию функции, которая изменяется только при изменении значений одной из зависимостей.
Это полезно при передаче обратных вызовов оптимизированным дочерним компонентам, которые полагаются на равенство ссылок для предотвращения ненужных рендерингов.
const callbackValue = useCallback(() => computeFunc(paramA, paramB), [paramA, paramB]);
25. В чем разница между useMemo
и useCallback
?
useMemo
используется для мемоизации результата вычисления, в то время как useCallback
используется для мемоизации самой функции.
useMemo
кэширует вычисленное значение и возвращает его при последующих рендерах, если зависимости не изменились.
useCallback
кэширует саму функцию и возвращает тот же экземпляр, если зависимости не изменились.
26. Что такое React Context?
React Context — это функция, которая позволяет передавать данные через дерево компонентов без ручной передачи входных параметров на каждом уровне. Он позволяет создать глобальное состояние, к которому может получить доступ любой компонент в дереве, независимо от его положения. Контекст полезен, когда вам нужно поделиться данными между несколькими компонентами, которые не связаны напрямую через входные параметры. React Context API состоит из трех основных частей:createContext
: Эта функция используется для создания нового объекта контекста.Context.Provider
: этот компонент используется для предоставления значения контексту. Он оборачивает компоненты, которым требуется доступ к значению.Context.Consumer
или хукuseContext
: этот компонент или хук используется для получения значения из контекста. Его можно использовать в любом компоненте поставщика контекста.
27. Для чего используется useContext
и как он работает?
В типичном React-приложении данные передаются сверху вниз (от родительского компонента к дочернему) с помощью входных параметров. Однако такой способ использования может оказаться слишком громоздким для некоторых видов пропсов (например, выбранный язык, тема пользовательского интерфейса), которые должны быть переданы многим компонентам в приложении. Контекст предоставляет способ обмена такими данными между компонентами без необходимости явной передачи входных параметров через
каждый уровень дерева.
Компонент, вызывающий useContext
, всегда будет перерисовываться, когда значение контекста изменяется. Если повторный рендеринг компонента требует больших затрат, его можно оптимизировать с помощью мемоизации.
Пример работы с контекстом в React.const App = () => { const theme = useContext(ThemeContext); return ( <div style={{ color: theme.palette.primary.main }}> Some div </div> ); }
28. Для чего используется useRef
и как он работает?
useRef
возвращает изменяемый объект. Поле current
которого инициализируется переданным аргументом. Возвращаемый объект будет сохраняться в течение всего времени существования компонента и не будет изменяться от рендера к рендерингу.
Обычным вариантом использования является обращение к элементу-потомку в императивном стиле. Т.е. с помощью ref
мы можем явно ссылаться на элемент DOM.
const App = () => { const inputRef = useRef(null); const buttonClick = () => { inputRef.current.focus(); } return ( <> <input ref={inputRef} type="text" /> <button onClick={buttonClick}>Focus on input tag</button> </> ) }
29. Что такое React.memo()
?
React.memo()
— это компонент высшего порядка. Если ваш компонент всегда рендерит одно и то же с неизменяемыми входными параметрами, вы можете обернуть его в вызов React.memo()
для повышения производительности в некоторых случаях, тем самым запоминая результат. Это означает, что React будет использовать результат последнего рендера, избегая повторного рендеринга. React.memo()
влияет только на изменения входных параметров. Если функциональный компонент обернут в React.memo
и использует useState
, useReducer
или useContext
, он будет повторно отрисован при изменении состояния или контекста.
import { memo } from 'react'; const MemoComponent = memo(MemoComponent = (props) => { // ... });
30. Что такое React Fragment?
Возврат нескольких элементов из компонента является обычной практикой в React. Фрагменты позволяют сформировать список дочерних элементов без создания лишних узлов DOM дереве.<> <OneChild /> <AnotherChild /> </> // или <React.Fragment> <OneChild /> <AnotherChild /> </React.Fragment>
31. Что такое React Reconciliation?
Согласование — это алгоритм React, используемый для различия одного дерева элементов от другого, чтобы определить части, которые необходимо заменить. Reconciliation — это алгоритм, лежащий в основе того, что мы привыкли называть Virtual DOM. Определение звучит примерно так: когда вы рендерите приложение React, дерево элементов, описывающее приложение, генерируется в зарезервированной памяти. Это дерево затем включается в среду рендеринга - например, браузерное приложение, оно транслируется в набор операций DOM. При обновлении состояния приложения создается новое дерево. Новое дерево сравнивается с предыдущим, чтобы рассчитать и включить именно те операции, которые необходимы для перерисовки обновленного приложения.32. Зачем нужны ключи в списках при использовании map()
?
Ключи помогают React определить, какие элементы были изменены, добавлены или удалены. Они должны быть указаны так, чтобы React мог сопоставить элементы массива с течением времени. Лучший способ выбрать ключ — использовать строку, которая будет четко отличать элемент списка от его соседей. Чаще всего в качестве ключей вы будете использовать идентификаторы из ваших данных.
const languages = [ { id: 1, lang: "JavaScript", }, { id: 2, lang: "TypeScript", }, { id: 3, lang: "Python", }, ]; const App = () => { return ( <div> <ul>{languages.map((language) => ( <li key={`${language.id}_${language.lang}`}>{language.lang}</li> ))} </ul> </div> ); }
33. Как обрабатывать асинхронные действия в Redux Thunk?
Чтобы использовать Redux Thunk, вам нужно импортировать его как промежуточное ПО (middleware). Создатели действий (action creator) должны возвращать не просто объект, а функцию, которая принимаетdispatch
в качестве параметра.
export const addUser = ({ firstName, lastName }) => { return dispatch => { dispatch(addUserStart()); } axios.post('https://jsonplaceholder.typicode.com/users', { firstName, lastName, completed: false }) .then(res => { dispatch(addUserSuccess(res.data)); }) .catch(error => { dispatch(addUserError(error.message)); }) }
34. Как отслеживать изменения в поле объекта в функциональном компоненте?
Для этого нужно воспользоваться хукомuseEffect
и передать поле объекта в массив зависимостей.
useEffect(() => { console.log('Changed!') }, [obj.someField])
35. Как получить доступ к элементу DOM?
Рефы создаются с помощьюReact.createRef()
или useRef()
и прикрепляются к элементам React через атрибут ref
. Обратившись к созданной ссылке, мы можем получить доступ к элементу DOM с помощью ref.current
.
const App = () => { const myRef = useRef(null); const handleClick = () => { console.log(myRef.current); // Accessing the DOM element }; return ( <div> <input type="text" ref={myRef} /> <button onClick={handleClick}>Click Me</button> </div> ); } export default App;
36. Что такое пользовательский хук?
Custom hook — это функция, которая позволяет повторно использовать логику между различными компонентами. Это способ инкапсуляции многократно используемой логики, чтобы ее можно было легко использовать совместно и повторно использовать в нескольких компонентах. Пользовательские хуки - это функции, которые обычно начинаются со словаuse
и могут вызывать другие хуки при необходимости.
37. Что такое SSR (рендеринг на стороне сервера)?
Серверная визуализация (SSR) — это метод, используемый для рендеринга страниц на сервере и отправки полностью визуализированной страницы клиенту для отображения. Он позволяет серверу генерировать полную HTML-разметку веб-страницы, включая ее динамическое содержимое, и отправлять ее клиенту в качестве ответа на запрос. При традиционном подходе к рендерингу на стороне клиента клиент получает минимальную HTML-страницу, а затем делает дополнительные запросы к серверу за данными и ресурсами, которые используются для рендеринга страницы на стороне клиента. Это может привести к замедлению начальной загрузки страницы и негативно повлиять на поисковую оптимизацию (SEO), поскольку поисковые роботы испытывают трудности с индексированием контента на основе JavaScript. При использовании SSR сервер заботится о рендеринге веб-страницы, выполняя необходимый код JavaScript для создания окончательного HTML-кода. Это означает, что клиент получает полностью отрисованную страницу с сервера, что снижает потребность в дополнительных запросах ресурсов. SSR улучшает время начальной загрузки страницы и позволяет поисковым системам легко индексировать контент, что приводит к улучшению SEO. SSR обычно используется в фреймворках и библиотеках, таких как Next.js для React и Nuxt.js для Vue.js, для обеспечения возможностей рендеринга на стороне сервера. Эти платформы обрабатывают логику рендеринга на стороне сервера, упрощая реализацию SSR.38. Каковы преимущества использования SSR?
- Улучшенное время начальной загрузки: SSR позволяет серверу отправлять клиенту полностью визуализированную HTML-страницу, уменьшая объем обработки, требуемой на стороне клиента. Это сокращает время начальной загрузки, так как пользователь быстрее видит всю страницу.
- SEO-оптимизация: поисковые системы могут эффективно сканировать и индексировать содержимое SSR-страниц, поскольку полностью визуализированный HTML-код доступен в первоначальном ответе. Это улучшает видимость в поисковых системах и помогает улучшить рейтинг в поиске.
- Специальные возможности: SSR гарантирует, что содержимое будет доступно пользователям, у которых отключен JavaScript или которые используют специальные возможности. Генерируя HTML на сервере, SSR обеспечивает надежное и доступное взаимодействие с пользователем для всех пользователей.
- Производительность в средах с низкой пропускной способностью: SSR уменьшает объем данных, необходимых для загрузки клиентом, что делает его выгодным для пользователей в средах с низкой пропускной способностью или высокой задержкой. Это особенно важно для мобильных пользователей или пользователей с медленным подключением к Интернету.
39. Какие основные функции Next.js вы знаете?
getStaticProps
: этот метод используется для получения данных во время сборки и предварительного рендеринга страницы в виде статического HTML. Он гарантирует, что данные будут доступны во время сборки и не будут изменяться при последующих запросах.
export async function getStaticProps() { const res = await fetch('https://api.example.com/data'); const data = await res.json(); return { props: { data } }; }
getServerSideProps
: Этот метод используется для получения данных по каждому запросу и предварительного рендеринга страницы на сервере. Его можно использовать, когда вам нужно получить данные, которые могут часто изменяться или зависят от пользователя.
export async function getServerSideProps() { const res = await fetch('https://api.example.com/data'); const data = await res.json(); return { props: { data } }; }
getStaticPaths
: этот метод используется в динамических маршрутах для указания списка путей, которые должны быть предварительно отрисованы во время сборки. Обычно используется для получения данных для динамических маршрутов с параметрами.
export async function getStaticPaths() { const res = await fetch('https://api.example.com/posts'); const posts = await res.json(); const paths = posts.map((post) => ({ params: { id: post.id } })); return { paths, fallback: false }; }
40. Что такое линтеры?
Линтер — это инструменты, используемые для проверки исходного кода на наличие потенциальных ошибок, багов, стилистических несоответствий и проблем с сопровождением. Они помогают применять стандарты кодирования и обеспечивать качество и согласованность кода в проекте. Линтеры сканируют исходный код и сравнивают его с набором предопределенных правил или рекомендаций. Эти правила могут включать в себя соглашения о синтаксисе и форматировании, рекомендации, потенциальные ошибки. Когда анализатор кода обнаруживает нарушение правила, он генерирует предупреждение или ошибку, выделяя конкретную строку или строки кода, требующие внимания. Использование линтера может дать несколько преимуществ:- Качество кода: Анализаторы кода помогают выявлять и предотвращать потенциальные ошибки, антипаттерны, что приводит к повышению качества кода.
- Согласованность: Линтеры применяют соглашения о кодировании и рекомендации по стилю, обеспечивая единообразное форматирование и структуру кода во всей кодовой базе, даже когда несколько разработчиков работают над одним и тем же проектом.
- Удобство сопровождения: Выявляя проблемы на ранней стадии и продвигая надлежащие методы кодирования, линтеры способствуют сопровождению кода, упрощая понимание, изменение и расширение кодовой базы.
- Эффективность: Линтер может сэкономить время разработчиков, автоматизируя процессы проверки кода и выявляя распространенные ошибки до того, как они могут вызвать проблемы во время разработки или в рабочей среде.
41. Какие архитектурные решения для React вы знаете?
Существует несколько архитектурных решений и паттернов для построения React-проектов. Вот некоторые из них:- MVC (Model-View-Controller): MVC — это традиционный архитектурный шаблон, который разделяет приложение на три основных компонента — модель, представление и контроллер. React можно использовать на уровне View для рендеринга пользовательского интерфейса, в то время как другие библиотеки или фреймворки могут быть использованы для уровней Model и Controller.
- Flux: Flux — это архитектура приложений, представленная специально для приложений React. Он следует однонаправленному потоку данных, в котором данные передаются в одном направлении, что упрощает понимание и отладку изменений состояния приложения.
- Atomic Design: Atomic Design не является специфичным для React, а представляет собой методологию проектирования, которая делит пользовательский интерфейс на более мелкие, многократно используемые компоненты. Он поощряет создание небольших, самодостаточных компонентов, которые могут быть скомпонованы для создания более сложных пользовательских интерфейсов.
- Шаблон контейнера и компонента: Этот шаблон отделяет представление (Component) от логики и управления состоянием (Container). Компоненты отвечают за рендеринг пользовательского интерфейса, в то время как контейнеры обрабатывают бизнес-логику и управление состоянием.
- Feature-Sliced Design: Это современный архитектурный подход, используемый для организации и структурирования приложений React. Он направлен на решение проблем масштабируемости, удобства обслуживания и повторного использования путем разделения кодовой базы приложения на основе функций или модулей.