Вопросы и ответы React собеседования 2023 - Часть 2

2 года назад·6 мин. на чтение

Актуальный список вопросов и ответов по ReactJS на интервью 2023 - Часть 2

1. Что такое JSX?

  • JSX — это расширение синтаксиса для JavaScript, обладающее всеми возможностями JavaScript.
  • Вы можете внедрить любое выражение JavaScript в JSX, заключив его в фигурные скобки. После компиляции выражения JSX становятся обычными объектами JavaScript.
  • Это означает, что вы можете использовать JSX внутри операторов if и циклов for, назначать его переменным, принимать в качестве аргументов и возвращать из функций.

2. Каков эквивалент следующего кода с использованием React.createElement?

const element = <h1 className="greeting">Hello, world!</h1>;
Эквивалент с использованием React.createElement будет выглядеть следующим образом:
const element = React.createElement(
  "h1",
  { className: "greeting" },
  "Hello, world!"
);

3. Что такое Redux?

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

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

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

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

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

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

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

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

// Хук useDebounce

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);

  return (
    <div>
      <p>
        Current Value: {value} | Debounced Value: {lastValue}
      </p>
      <button onClick={() => setValue(value + 1)}>Increment</button>
    </div>
  );
};

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

// Хук useCopyToClipboard

function useCopyToClipboard(content) {
  const [isCopied, setIsCopied] = useState(false);

  const copy = useCallback(() => {
    navigator.clipboard
      .writeText(content)
      .then(() => setIsCopied(true))
      .then(() => setTimeout(() => setIsCopied(false), 1250))
      .catch((err) => alert(err));
  }, [content]);
  return [isCopied, copy];
}
// Использование
export default function App() {
  const [isCopied, copy] = useCopyToClipboard("Text to copy!");
  return <button onClick={copy}>{isCopied ? "Copied!" : "Copy"}</button>;
}

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

  • 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>);
Подробности можно найти в статье Что за хук useId в React?.

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

Мы можем использовать пакет 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.

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

// Компонент высшего порядка
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;
// Использование

import UserListComponent from "./UserListComponent.js"; // импорт компонента
import WithLoading from "./withLoading.js"; // импорт HOC

const ListWithLoading = WithLoading(UserListComponent); // обернем компонент в HOC

const App = () => {
  const [loading, setLoading] = useState(true);
  const [users, setUsers] = useState([]);

  useEffect(() => {
    // запрос данных
    const dataFromApi = ["this is coming from API call", "don't show loader"];
    
    // в это время загрузчик будет показан в HOC
    // данные получены
    setUsers([...dataFromApi]);
    setLoading(false);
  }, []);

  return <ListWithLoading isLoading={loading} users={users} />;
};

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

  • 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>
    </>
  );
}

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

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>;
}

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

В JSX имена тегов нижнего регистра считаются тегами HTML. Однако имена тегов в нижнем регистре с точкой (аксессор свойства) не являются таковыми.
  • <person /> компилируется в React.createElement('person') (тег html)
  • компилируется в React.createElement(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} />;
}

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

  • 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

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

import React, { useEffect, useRef } from "react";

const SearchPage = () => {
  const textInput = useRef(null);

  useEffect(() => {
    textInput.current.focus();
  }, []);

  return (
    <div>
      <input ref={textInput} type="text" />
    </div>
  );
};
Еще больше вопросов с собеседований

Что могут спросить на фронтенд собеседовании?

месяц назад·2 мин. на чтение

Рассмотрим вопросы, которые вполне могут спросить на фронтенд-собеседовании.

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

1. Объясните различия между JavaScript и TypeScript.

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

2. Расскажите о различных подходах к организации кода в JavaScript.

В JavaScript существуют различные методологии и паттерны для организации кода, такие как модульный подход, паттерн MVP (Model-View-Presenter), паттерн MVVM (Model-View-ViewModel) и другие. Каждый из них имеет свои преимущества и недостатки, и правильный выбор зависит от конкретной задачи и проекта.

3. Что такое Event Loop в JavaScript?

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

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

Фронтенд разработчик должен быть знаком с различными инструментами и технологиями для оптимизации производительности веб-приложений. Например, использование инструментов для сжатия и минимизации кода, улучшение кэширования, асинхронная загрузка ресурсов, оптимизация изображений и другие. Также важно иметь опыт работы с DevTools для анализа и оптимизации производительности.

5. Расскажите о своем опыте работы с адаптивным и отзывчивым дизайном.

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

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

В React можно использовать различные методы для передачи данных между компонентами, такие как прокидывание props сверху вниз, использование контекста и Redux для управления состоянием приложения. Фронтенд разработчик должен иметь хорошее понимание этих методов и уметь выбрать правильный подход в зависимости от конкретной ситуации. На собеседовании могут быть заданы вопросы, направленные на оценку вашего понимания и применения этих знаний. Подготовка и самообразование в этих вопросах помогут уверенно пройти собеседование и достичь желаемой должности.