React Flashcards
Что происходит, когда вы вызываете setState?
Во-первых, если был вызван setState, то React захочет объединить объект, который вы отправили в setState с текущим состоянием компонента. Это позволит начать процесс согласования. Конечной целью согласования является обновление пользовательского интерфейса на основе его нового состояния наиболее эффективным из возможных способов. Для этого React сформирует новое дерево элементов (которое можно рассматривать как объектное представление вашего пользовательского интерфейса). Как только React получает это дерево, чтобы выяснить как интерфейс должен измениться в ответ на новое состояние, React сравнит новое дерево с предыдущим деревом элементов. В этом процессе, React узнает точные изменения, которые произошли. Зная эти изменения, React получит возможность провести изменения в интерфейсе только там, где это необходимо и этим минимизировать количество изменений.
Какая разница между Элементом и Компонентом в React?
Проще говоря, элемент в React описывает то, что вы хотите видеть на экране. Если точнее, то элемент в React является объектным представлением некого пользовательского интерфейса.
Компонент в React является функцией или классом, который при необходимости принимает данные и возвращает элемент (обычно в виде JSX, который преобразуется в вызов createElement)
Для дополнительной информации изучите раздел React Elements vs React Components
Когда вам использовать Class Component вместо Functional Component?
Если ваш компонент имеет состояние или содержит используемые методы значимые для компонента, то используйте Class component. В других случаях используйте Functional component.
Что за refs в React и в чем их важность?
Refs являются запасным выходом, который позволяет вам получить прямой доступ к элементу DOM или состоянию компонента. Чтобы их использовать вы добавляете атрибут ref в ваш компонент, значение которого является функцией обратного вызова, которая получит базовый элемент DOM или установленный экземпляр компонента в качестве первого аргумента.
class UnControlledForm extends Component { handleSubmit = () => { console.log("Input Value: ", this.input.value) } render () { return (
this.input = input} /> Submit ) } } Отметим, что наше поле ввода имеет атрибут ref, значение которого является функцией. Эта функция получает реальный элемент DOM на вход, который мы затем вставим в экземпляр для того, чтобы получить доступ к нему внутри функции handleSubmit.
Часто неверно полагают, что необходимо использовать класс компонента для того, чтобы использовать refs, но refs могут быть использованы с функциональными компонентами за счет использования замыкания:
function CustomForm ({handleSubmit}) { let inputElement return ( handleSubmit(inputElement.value)}> inputElement = input} /> Submit
)
}
Что за keys в React и чем их важность?
Keys (ключи) помогают React отследить какие элементы были изменены, добавлены или удалены из списка.
render () { return ( <ul> {this.state.todoItems.map(({task, uid}) => { return <li>{task}</li> })} </ul> ) } Важно, чтобы каждый ключ был уникальным между “собратьями”. Мы уже говорили о процессе согласования и в частности о процессе сравнения нового дерева элементов с предыдущим. Keys делают этот процесс более эффективным при работе со списками, потому что React может использовать ключ на дочерний элемент, чтобы быстро узнать если элемент является новым или если он был просто перемещен при сравнении деревьев элементов. Не только keys делают этот процесс более эффективным, но без них, React не сможет узнать какое локальное состояние соответствует какому пункту при его перемещении. Поэтому не пренебрегайте использованием keys при применении map.
В чем разница между controlled и uncontrolled компонентами?
Одна из основных идей React, это наличие контроля над компонентами и управление их собственным состоянием. Что случится если мы отправим чистый HTML элементов формы (input, select, textarea и т.д.) в общей куче? Должны ли мы иметь React, как “единственный источник правды” или мы должны позволить, чтобы данные формы существовали в DOM в HTML-форме? Эти два вопроса лежат в основе контролируемых (controlled) и неконтролируемых (uncontrolled) компонентов.
Контролируемый компонент — это такой компонент, где React осуществляет контроль и является единственным источником правды для данных формы. Как вы можете видеть ниже, username существует не в DOM, а нашем состоянии компонента. Всякий раз, когда хотим обновить username, мы вызываем setState, как мы уже привыкли.
class ControlledForm extends Component { state = { username: '' } updateUsername = (e) => { this.setState({ username: e.target.value, }) } handleSubmit = () => {} render () { return (
Submit ) } } Некотролируемый компонент — это такой компонент, где ваши данные формы обрабатываются в DOM, а не внутри вашего компонента.
class UnControlledForm extends Component { handleSubmit = () => { console.log("Input Value: ", this.input.value) } render () { return (
this.input = input} /> Submit ) } } Хотя неконтролируемые компоненты обычно проще в реализации, так как вы просто берете значение из DOM используя refs, рекомендуется использовать контролируемые компоненты. Основная причина этого в том, что контролируемые компоненты поддерживают мгновенную проверку полей, позволяют вам условно отключать/включать кнопки, устанавливать формат входных данных и, вообще, более отражают суть React.
В какой момент жизненного цикла вы применяется AJAX запросы и почему?
AJAX запросы должны идти в момент события componentDidMount.
Для этого есть несколько причин:
Следующая реализация алгоритма сверки в React будет иметь возможность запускать и останавливать рендеринг для повышения производительности. Одним из результатов нововведений является то, что componentWillMount (часть цикла событий, где возможно стоит реализовать AJAX-запрос) будет “не детерминированным”. Это означает то, то React может вызывать componentWillMount в разное время, когда он чувствует в этом необходимость. Это, очевидно, плохая формула для создания AJAX-запроса.
Вы не можете гарантировать, что AJAX-запрос не будет разрешен (resolve) перед моментом монтирования компонента. Если да, то это будет означать, что вы пытаетесь выполнить setState над демонтированным компонентом и вы обязательно получите сообщение об этом от React. Делайте AJAX-запросы в componentDidMount, чтобы гарантировать, что компонент для обновления присутствует.
Что делает и почему важен shouldComponentUpdate?
Выше мы уже говорили о сверке и что делает React, когда вызван setState. В жизненном цикле компонента имеется метод shouldComponentUpdate, который позволяет нам отказаться от участия в процессе сравнения для некоторых компонентов (и их дочерних компонентов). Зачем нам это вообще нужно делать? Как отмечалось выше, “цель сравнения в том, чтобы самым эффективным путем обновить интерфейс на основе нового состояния”. Если вы знаете, что часть интерфейса не изменится, то нет причин, заставлять React пройти через трудности, чтобы понять это. При возвращения false из shouldComponentUpdate, React будет понимать, что текущий компонент и все его дочерние компоненты останутся такими же, какими являются в данный момент.
Как вы укажите React работать в режиме Production и как это сделать?
Обычно вы можете использовать метод DefinePlugin в Webpack для установки NODE_ENV в production. Это вырежет такие вещи, как propType валидацию и другие предупреждения. Кроме того, это хорошая идея, чтобы минимизировать ваш код, потому что React использует Uglify для удаления “мертвого кода” и комментариев, что позволит сильно уменьшить размер сборки.
Почему необходимо использовать React.Children.map(props.children, () => ) вместо props.children.map(() => ) ?
Нет гарантии, что props.children будет массивом.
Взгляните на код:
<h1>Welcome.</h1>
Если внутри Parent вы попытаетесь вызвать props.children.map, то это вызовет ошибку, потому что props.children является объектом, а не массивом.
React отработает с props.children только в том случае, если родитель имеет более одного дочернего элемента, как здесь:
<h1>Welcome.</h1>
<h2>props.children will now be an array</h2>
Вы должны использовать React.Children.map, потому что эта реализация учитывает, что props.children может быть как объектом, так и массивом.
Опишите, как в React обрабатываются события?
Чтобы решить проблемы кроссбраузерной совместимости, вашим обработчикам в React будут переданы экземпляры SyntheticEvent, которые являются в React обертками над нативными событиями браузеров. Эти искусственные события имеют такой же интерфейс как и у нативных методов, которые вы используете, за исключение того, что они одинаково хорошо работают во всех браузерах.
Интересно то, что React не назначает события на дочерние элементы сам. React будет слушать все события на верхнем уровне, используя простой слушатель событий. Это хорошо для производительности и также означает, что React не нужно беспокоиться об отслеживании при обновлении DOM.
В чем разница между createElement и cloneElement?
createElement мы получаем из JSX и его React использует для создания элементов (объектное представление некоторого интерфейса). cloneElement используется для клонирования элемента и отправки ему новых параметров.
Какой второй аргумент можно передать опционально в setState и какова его цель?
Функция обратного вызова, которая будет вызываться после выполнения функции setState и отрисовки компонента.
Мы еще не поговорили о том, что это setState является асинхронным, поэтому он принимает вторым параметром функцию обратного вызова. Как правило, лучше использовать другой метод, а не полагаться на эту функцию обратного вызова. Но нужно знать, что эта возможность есть.
this.setState(
{ username: ‘tylermcginnis33’ },
() => console.log(‘setState has finished and the component has re-rendered.’)
)
Что не так с этим кодом? this.setState((prevState, props) => { return { streak: prevState.streak + props.count } })
С кодом все отлично :-) Такой вариант редко используется и не достаточно хорошо известен, но вы можете отправить функцию в setState, которая получает предыдущее состояние и параметры props и возвращает новое состояние, также как мы делали выше. И это не только не плохой код, но он также активно рекомендуется если вы обновляете состояние на основании предыдущего состояния.
Что такое React?
React — это JavaScript-библиотека с открытым исходным кодом, разработанная Facebook для создания сложных интерактивных пользовательских интерфейсов в приложениях.
Ключевым моментом является понимание цели React — удобное создание компонентов пользовательского интерфейса.
Чем React отличается от других библиотек?
Ответ на этот вопрос, скорее всего, будет зависеть от вашего личного опыта, потому что особенностей много, но каждый ценит разные вещи.
Несколько вариантов ответа:
Например, AngularJS (1.x) используется для создания приложения путем расширения разметки HTML и ввода различных конструкций (например, директив, контроллеров, служб) во время выполнения. Но зачастую возникают проблемы с архитектурой приложения.
React фокусируется исключительно на создании компонентов — это не про архитектуру приложения. Зато это позволяет разработчику выбирать архитектуру, которую они считают лучшей
Недавно я переносил приложение с AngularJS на React. Несколько различий, которые я обнаружил… (тут вы описываете опыт взаимодействия и важные отличия)
Будьте также готовы задать ответить на следующие вопросы:
В каких случаях вы выбираете работу на React по сравнению с Angular или React вместо Vue?
Какие подводные камни могут возникнуть при разработке React-приложения?
Перенося приложение из AngularJS в React сколько примерно кода вы сможете использовать повторно?
Что происходит во время жизненного цикла компонента React?
Жизненный цикл компонентов высокого уровня
На самом высоком уровне компоненты React имеют события жизненного цикла, которые подразделяются на три общие категории:
Инициализация;
Обновление свойств
Разрушение
Каждый компонент определяет эти события, как механизм управления его свойствами, состоянием и визуализацией. Понимание этих трех общих категорий должно помочь вам четко визуализировать, когда необходимо применять определенную логику.
Например, компоненту может потребоваться добавить обработчики событий в DOM, когда он будет создаваться впервые. Тем не менее, вероятно, следует удалить эти обработчики событий, когда компонент отключается от DOM, так что нерелевантная обработка не возникает.
class MyComponent extends React.Component { // when the component is added to the DOM... componentDidMount() { window.addEventListener('resize', this.onResizeHandler); }
// when the component is removed from the DOM... componentWillUnmount() { window.removeEventListener('resize', this.onResizeHandler); }
onResizeHandler() { console.log('The window has been resized!'); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 class MyComponent extends React.Component { // when the component is added to the DOM... componentDidMount() { window.addEventListener('resize', this.onResizeHandler); }
// when the component is removed from the DOM... componentWillUnmount() { window.removeEventListener('resize', this.onResizeHandler); }
onResizeHandler() {
console.log(‘The window has been resized!’);
}
}
Жизненный цикл компонентов низкого уровня
ReactВнутри этих трех общих категорий существует ряд методов, которые могут быть использованы любым компонентом React для более точного управления обновлениями. Понимание того, как, что и когда работает, является ключом к созданию стабильных компонентов и управлению процессом рендеринга.
Взгляните на изображение выше. События в разделе «Инициализация» происходят только тогда, когда компонент сначала инициализируется или добавляется в DOM. Точно так же события в разделе «Разрушение» происходят только один раз (когда компонент удаляется из DOM). Однако события в разделе «Обновление» происходят каждый раз при изменении свойств или состояния компонента.
Например, компоненты будут автоматически повторно отображать себя в любое время после изменения их свойств или состояния. Однако в некоторых случаях, компонент может не нуждаться в обновлении, поэтому предотвращение повторного рендеринга компонента может повысить производительность вашего приложения.
class MyComponent extends React.Component {
// only re-render if the ID has changed!
shouldComponentUpdate(nextProps, nextState) {
return nextProps.id === this.props.id;
}
}
1
2
3
4
5
6
class MyComponent extends React.Component {
// only re-render if the ID has changed!
shouldComponentUpdate(nextProps, nextState) {
return nextProps.id === this.props.id;
}
}
Что вы можете рассказать о JSX?
В то же время, когда Facebook впервые выпустил React, был представлен новый диалект JavaScript под названием JSX, который внедряет необработанные HTML-шаблоны внутри кода JavaScript. JSX-код сам по себе не может быть прочитан браузером: он должен быть переведен в традиционный JavaScript с использованием таких инструментов, как Babel и webpack.
class MyComponent extends React.Component { render() { let props = this.props;
return ( <div> <a href="%7Bprops.url%7D">{props.name}</a> </div> ); } } 1 2 3 4 5 6 7 8 9 10 11 class MyComponent extends React.Component { render() { let props = this.props;
return ( <div> <a href="%7Bprops.url%7D">{props.name}</a> </div> ); } } Важные моменты:
React-разработчикам не нужно использовать JSX (и ES2015) для написания React-приложения;
ES2015 представил множество новых функций для JavaScript, что делает запись больших приложений намного проще, чем раньше: классы, блокировка области с помощью let и новый оператор с расширением — это лишь небольшая часть дополнений
import AnotherClass from ‘./AnotherClass’;
class MyComponent extends React.Component { render() { let props = this.props;
return ( <div>
</div> ); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 import AnotherClass from './AnotherClass';
class MyComponent extends React.Component { render() { let props = this.props;
return ( <div>
</div> ); } } Но пока ES2015 всё ещё распространяется, он по-прежнему поддерживается далеко не всеми крупными браузерами — поэтому для преобразования всего в устаревший код ES5 необходимы такие инструменты, как Babel или webpack.
Вы знакомы с Flux?
Flux — это архитектурный шаблон, который обеспечивает однонаправленный поток данных. Его основная цель — контролировать производные данные, чтобы несколько компонентов могли взаимодействовать с этими данными без риска загрязнения.
Flux обычно используется разработчиками React, поскольку компоненты React являются декларативными. Представленный пользовательский интерфейс представляет собой просто функцию состояния.
react.js interview questions
Flux относительно прост в концепции, но важно продемонстрировать глубокое понимание его реализации. Давайте рассмотрим важные несколько дискуссионных вопросов.
Flux vs MVC
Традиционные шаблоны MVC хорошо зарекомендовали себя для разделения проблем данных (Model), UI (View) и логики (Controller), но многие веб-разработчики обнаружили ограничения, поскольку приложения растут по размеру. В частности, архитектуры MVC часто сталкиваются с двумя основными проблемами:
Каскадные обновления часто приводят к запутанной сети событий, которые трудно отлаживать;
Отсутствие целостности данных: данные модели могут быть изменены с любого места, что дает непредсказуемые результаты в пользовательском интерфейсе.
При использовании Flux, любой компонент сможет восстановить свое состояние на основе данных, предоставленных Store. Шаблон Flux также обеспечивает целостность данных, ограничивая прямой доступ к общим данным.
Разница, по сравнению с AngularJS (1.x)
Компоненты пользовательского интерфейса в AngularJS обычно полагаются на некоторую внутреннюю область $scope для хранения своих данных. Эти данные могут быть напрямую изменены с помощью компонента пользовательского интерфейса или любого доступного доступа $scope.
Напротив, Flux приветствует использование неизменяемых данных. Поскольку хранилище является центральным органом по всем данным, любые изменения этих данных должны происходить в хранилище.
Тестирование
Одним из наиболее важных аспектов создания Flux-приложений, является то, что их компоненты удобно тестировать. Разработчики могут воссоздать и протестировать состояние любого компонента React, просто обновив хранилище. Прямые взаимодействия с пользовательским интерфейсом (с помощью таких инструментов, как Selenium) в большинстве случаев больше не нужны.
Что такое компоненты без локального состояния?
Компоненты без состояния представляют собой не что иное, как чистые функции, которые делают DOM основанным исключительно на предоставляемых им свойствах.
const StatelessCmp = props => { return ( <div> {props.name}: {props.birthday} </div> ); };
// --- ReactDOM.render( , document.getElementById('main') ); 1 2 3 4 5 6 7 8 9 10 11 12 13 const StatelessCmp = props => { return ( <div> {props.name}: {props.birthday} </div> ); };
// --- ReactDOM.render( , document.getElementById('main') ); Этот компонент не нуждается в каком-либо внутреннем состоянии, не говоря уже о конструкторах или обработчиках жизненного цикла. Выходной компонент является функцией предоставляемых ему свойств.
Что такое Виртуальная DOM?
Виртуальная DOM является представлением реальной DOM в памяти. React создает кэш структуры данных в памяти, вычисляет результирующие различия и затем эффективно обновляет отображаемую DOM браузера. Это позволяет программисту писать код, как будто вся страница отображается при каждом изменении, в то время как библиотеки React отображают только те подкомпоненты, которые действительно изменяются.