0
56018

Топ 15 вопросов о React.JS на собеседовании

React.JS быстрый, с компонентной моделью и большим комьюнити, которое даст совет по любому крашу. Но на собеседовании вас спросят о другом.

React.JS

1. Что делает setState?

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

React setState

С setState не нужно париться: достаточно вызвать эту функцию с новым значением в виде объекта:

this.setState({someField:someValue})

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

2. В чем разница между элементом и компонентом React.JS?

  1. Если просто: элемент – это то, что вы хотите видеть на экране.
  2. Если не так просто: элемент – объектное представление некоторого пользовательского интерфейса.

С компонентом все иначе. Это класс или функция, что может принимать данные и возвращать элементы (обычно с использованием техники создания элементов React JSX).

3. В каких случаях Class Component лучше, чем Functional Component?

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

Functional Component

4. Что такое refs и с чем их едят?

Предположим, нам понадобилось «достучаться» к конкретному элементу и вызвать метод. React.JS refs нужен как раз для этого. Как использовать? Добавить атрибут ref в компонент для обратного вызова. Например:

class UnControlledForm extends Component {
  handleSubmit = () => {
    console.log("Input Value: ", this.input.value)
  }
  render () {
    return (
      <form onSubmit={this.handleSubmit}>
        <input
          type='text'
          ref={(input) => this.input = input} />
        <button type='submit'>Submit</button>
      </form>
    )
  }
}

Примечательно, что поле ввода с атрибутом ref, а его значение – это функция. Она получает DOM-элемент, который вставляется в экземпляр, чтобы после получить к нему доступ в функции handleSubmit. При этом можно работать как с классом компонента, так и с функциональными компонентами, используя замыкание:

function CustomForm ({handleSubmit}) {
  let inputElement
  return (
    <form onSubmit={() => handleSubmit(inputElement.value)}>
      <input
        type='text'
        ref={(input) => inputElement = input} />
      <button type='submit'>Submit</button>
    </form>
  )
}

5. React key – это...

Настоящая палочка-выручалочка, особенно в большом коде. Ключи отслеживают измененные, добавленные или удаленные из списка элементы. Делается это так:

render () {
  return (
    <ul>
      {this.state.todoItems.map(({task, uid}) => {
        return <li key={uid}>{task}</li>
      })}
    </ul>
  )
}

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

6. Как бы выглядел приведенный ниже элемент Twitter в React?

<Twitter username='tylermcginnis33'>
  {(user) => user === null
    ? <Loading />
    : <Badge info={user} />}
</Twitter>

import React, { Component, PropTypes } from 'react'
import fetchUser from 'twitter'

// fetchUser take in a username returns a promise
// which will resolve with that username's data.

class Twitter extends Component {
  // finish this
}

В этом примере потомок компонента Twitter – функция, и чтобы решить поставленную задачу, нужно обратиться к props.children в качестве ф-ии:

import React, { Component, PropTypes } from 'react'
import fetchUser from 'twitter'

class Twitter extends Component {
  state = {
    user: null,
  }
  static propTypes = {
    username: PropTypes.string.isRequired,
  }
  componentDidMount () {
    fetchUser(this.props.username)
      .then((user) => this.setState({user}))
  }
  render () {
    return this.props.children(this.state.user)
  }
}

Как писалось выше, мы обращаемся к React props children в качестве функции: вызываем ее, а затем передаем юзера.

Плюс приведенного шаблона в том, что родительский компонент отделен от дочернего. При этом «родитель» контролирует состояние, а потребитель данного компонента решает, как использовать переданные аргументы в UI.

Допустим, у нас есть другой файл, в котором мы хотим заменить Badge на Profile. Поскольку мы работаем с шаблоном render callback, то просто поменяем UI без изменения реализации родительского компонента Twitter:

<Twitter username='tylermcginnis33'>
  {(user) => user === null
    ? <Loading />
    : <Profile info={user} />}
</Twitter>

7. Разница между компонентами controlled и uncontrolled

Отличительной особенностью React.JS является управление компонентами и их состоянием.

Контролируемым называется такой компонент, в рамках которого React осуществляет контроль. В примере username существует в состоянии компонента, а не в DOM, и чтобы обновить username, просто вызываем setState:

class ControlledForm extends Component {
  state = {
    username: ''
  }
  updateUsername = (e) => {
    this.setState({
      username: e.target.value,
    })
  }
  handleSubmit = () => {}
  render () {
    return (
      <form onSubmit={this.handleSubmit}>
        <input
          type='text'
          value={this.state.username}
          onChange={this.updateUsername} />
        <button type='submit'>Submit</button>
      </form>
    )
  }
}

А вот к неконтролируемым относятся такие компоненты, в которых данные формы обрабатываются DOM. Для этого используется ref:

class UnControlledForm extends Component {
  handleSubmit = () => {
    console.log("Input Value: ", this.input.value)
  }
  render () {
    return (
      <form onSubmit={this.handleSubmit}>
        <input
          type='text'
          ref={(input) => this.input = input} />
        <button type='submit'>Submit</button>
      </form>
    )
  }
}

Вторые проще в реализации, ведь значения берутся из DOM с использованием refs. Только вот рекомендуется обратить внимание именно на контролируемые компоненты и разобраться в работе с ними. Дело в том, что они поддерживают быструю проверку полей, позволяют устанавливать формат входных данных и включать/отключать кнопки, а это «в стиле» React.

8. В каком моменте должны быть AJAX запросы и почему?

AJAX запросы

AJAX запросы делаются в методе componentDidMount. Это подкреплено двумя причинами:

  1. Во-первых, повысится производительность, ведь React сможет останавливать и запускать рендеринг. И напротив, если предпочесть componentWillMount, React будет вызывать его всякий раз, как увидит в этом необходимость. Для AJAX запроса componentWillMount – не лучший вариант.
  2. Во-вторых, componentDidMount гарантирует, что существует компонент для обновления. В противном случае могут посыпаться краши.

9. Что за зверь, этот shouldComponentUpdate?

О setState мы уже поговорили и выяснили, что он делает. Но что следует предпринять, дабы «защитить» некоторые компоненты от сравнения? Вот для этого и существует метод shouldComponentUpdate.

shouldComponentUpdate

Спросите, зачем это нужно? Ну, допустим, вы точно знаете, что часть UI не изменится. И зачем нам прогонять ее через сравнение, если это не несет никакого смысла? Здесь-то и пригодится наш «зверь». Возврат значения false из метода shouldComponentUpdate позволит React понять, что включенные в метод компоненты не нуждаются в сравнении и последующих изменениях.

10. Поговорим с React.JS: режим Production

Чтобы установить NODE_ENV в production обычно используется WebPack DefinePlugin. Это позволит удалить проверку propType и другие предупреждения. Также существенно сократится код, ведь в React.JS предусмотрен Uglify, который выбрасывает «мертвый код», оставляя лишь необходимое.

11. Почему React.Children.map(props.children, () => ), а не props.children.map(() => )?

А если props.children окажется не массивом, а объектом? Пример:

<Parent>
  <h1>Welcome.</h1>
</Parent>

Вызов props.children.map в «родителе» даст ошибку, ведь это как раз тот случай, когда props.children – объект, а не массив. React отработает, если дочерний элемент не один: их должно быть несколько. Взгляните:

<Parent>
  <h1>Welcome.</h1>
  <h2>props.children will now be an array</h2>
</Parent>

Вот почему использование React.Children.map наиболее предпочтительно: с такой реализацией props.children может выступать как массивом, так и объектом.

12. Опишите обработку событий в React.JS

Кроссбраузерная совместимость – одна из основных проблем, и чтобы ее решить, обработчикам React передаются экземпляры SyntheticEvent – оболочки над нативными браузерными событиями. Данные события искусственные и обладают тем же интерфейсом, что и обычные, вот только работают они одинаково хорошо во всех браузерах.

Кроссбраузерная совместимость

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

13. В чем разница между cloneElement и createElement?

  • cloneElement предназначен для точного копирования элемента и передачи ему необходимых параметров;
  • createElement – это то, что транслирует JSX, а также то, что использует React.JS для создания новых элементов, которые представляют пользовательский интерфейс.

14. Какой второй аргумент может быть передан в setState?

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

this.setState(
  { username: 'tylermcginnis33' },
  () => console.log('setState has finished and the component has re-rendered.')
)

15. Укажите на ошибку в приведенном коде

this.setState((prevState, props) => {
  return {
    streak: prevState.streak + props.count
  }
})

Ошибок нет. Впрочем, такой вариант используется крайне редко, поэтому вызывает вопросы. Тем не менее вы можете передать в React setState функцию, которая получает параметры props и предыдущее состояние, а также возвращает новое состояние по аналогии с примерами выше. Данный вариант кода является оптимальным в том случае, если текущее состояние обновляется на основании состояния предшествующего.

Также рекомендуем Вам посмотреть:

Дайджест материалов по трудоустройству в сфере IT
Как провалить 45-минутное техническое интервью
Изучение React. С чего начать?
Подборка материалов по JavaScript

РУБРИКИ В СТАТЬЕ

МЕРОПРИЯТИЯ

Искать мидлов или растить джунов?
26 февраля Онлайн Бесплатно
GameDev in Kazan 2020
29 февраля Казань Бесплатно
День открытых данных
06 марта Москва Бесплатно
Xride Meetup
27 февраля Санкт-Петербург Бесплатно

Комментарии 0

ВАКАНСИИ

Python Programmer
по итогам собеседования
Unity 3D Developer
по итогам собеседования
Programmer, Game (C++)
по итогам собеседования

ЛУЧШИЕ СТАТЬИ ПО ТЕМЕ

BUG