ChatGPT на русском языке, бесплатноНовости и обновления в Telegram
На sponsr есть решения ваших задач
Полезные видео о фронтенде. Подпишись на Rutube
Как добавить React на сайт
10 месяцев назад·6 мин. на чтение
Как добавить скрипты React на сайт. Вам не нужно создавать весь веб-сайт с помощью React. Можно ограничиться добавление React в HTML. Добавление React в HTML не требует установки, занимает пару минут и позволяет сразу начать писать интерактивные компоненты.
Содержание туториала по React
Вам не нужно создавать весь веб-сайт с помощью React. Можно ограничиться добавление React в HTML. Добавление React в HTML не требует установки, занимает пару минут и позволяет сразу начать писать интерактивные компоненты.
Шаг 2: Добавьте теги
На HTML-странице прямо перед закрывающим тегом
Добавление React в HTML
React с самого начала был разработан для постепенного внедрения. Большинство веб-сайтов не полностью построены (и не должны) с помощью React. В этом руководстве показано, как добавить немного интерактивности на существующую HTML-страницу. Попробуйте это на своем собственном веб-сайте или на пустом HTML-файле. Все, что вам нужно, это подключение к Интернету и текстовый редактор, такой как Блокнот или VS Code (Вот как настроить ваш редактор для подсветки синтаксиса).Шаг 1. Добавьте корневой HTML-тег
Сначала откройте HTML-страницу, которую хотите отредактировать. Добавьте пустой тег<div>
, чтобы отметить место, где вы хотите отобразить что-то с помощью React. Дайте этому <div>
уникальное значение атрибута id
. Например:
Он называется "корень" ("root"), потому что с него начинается дерево React. Такой корневой HTML-тег можно разместить в любом месте внутри тега<!-- ... существующий HTML ... --> <div id="like-button-root"></div> <!-- ... существующий HTML ... -->
<body>
. Оставьте его пустым, потому что React заменит его содержимое вашим компонентом React.
У вас может быть столько корневых тегов HTML, сколько вам нужно на одной странице.
Шаг 2: Добавьте теги script
На HTML-странице прямо перед закрывающим тегом </body>
добавьте три тега <script>
для следующих файлов:
- react.development.js позволяет вам определять компоненты React.
- react-dom.development.js позволяет React отображать HTML-элементы в DOM.
like-button.js
— это место, где будет находиться код нашего компонента, который напишем на следующем шаге.
Перед развертыванием веб-сайта в продакшн обязательно замените<!-- конец страницы --> <script src="https://unpkg.com/react@18/umd/react.development.js" crossorigin></script> <script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js" crossorigin></script> <script src="like-button.js"></script> </body> </html>
development.js
на production.min.js
. Сборки React для разработки предоставляют более полезные сообщения об ошибках, но сильно замедляют работу сайта.
Шаг 3: Создайте React компонент
Создайте файл с именемlike-button.js
рядом со своей HTML-страницей, добавьте этот фрагмент кода и сохраните файл. Этот код определяет React компонент под названием LikeButton
.
'use strict'; function LikeButton() { const [liked, setLiked] = React.useState(false); if (liked) { return 'You liked this!'; } return React.createElement( 'button', { onClick: () => setLiked(true), }, 'Like' ); }
Шаг 4: Добавьте React компонент на страницу
Наконец, добавьте три строки в конец файлаlike-button.js
. Эти строки кода находят <div>
, который мы добавили в HTML на первом шаге, создают корень React, а затем отображают React компонент кнопки «Нравится» внутри него:
Компоненты можно использовать повторно. Вы можете захотеть отобразить компоненты React в нескольких местах на одной HTML-странице. Это полезно, если части вашей страницы, основанные на React, отделены друг от друга. Вы можете сделать это, поместив несколько корневых тегов в свой HTML, а затем визуализировав компоненты React внутри каждого из них с помощьюconst rootNode = document.getElementById('like-button-root'); const root = ReactDOM.createRoot(rootNode); root.render(React.createElement(LikeButton));
ReactDOM.createRoot()
. Например:
- В
index.html
добавьте дополнительный элемент-контейнер<div id="another-root"></div>
. - В
like-button.js
добавьте в конце еще три строчки:
Если вам нужно отрендерить один и тот же компонент во многих местах, вы можете назначить CSS класс вместоconst anotherRootNode = document.getElementById('another-root'); const anotherRoot = ReactDOM.createRoot(anotherRootNode); anotherRoot.render(React.createElement(LikeButton));
id
для каждого корня, а затем найти их все.
Шаг 5: Минифицируйте JavaScript для продакшена
Неминифицированный JavaScript может значительно замедлить загрузку страниц для пользователей. Перед развертыванием веб-сайта в продакшене рекомендуется минимизировать его скрипты.- Если у вас нет шага минификации для скриптов, вот один из способов его настройки.
npx terser -c -m -o like-button.min.js -- like-button.js
- Если вы уже минимизируете скрипты своего приложений, ваш сайт будет готов к работе, если вы убедитесь, что развернутый HTML загружает версии React, заканчивающиеся на
production.min.js
следующим образом:
<script src="https://unpkg.com/react@18/umd/react.production.min.js" crossorigin ></script> <script src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js" crossorigin ></script>
React с JSX
Приведенные выше примеры основаны на функциях, изначально поддерживаемых браузерами. Вот почемуlike-button.js
использует вызов JavaScript функции, чтобы сообщить React, что отображать:
Однако React также предлагает возможность использовать вместо этого JSX, HTML-подобный синтаксис JavaScript:return React.createElement( 'button', { onClick: () => setLiked(true), }, 'Like' );
Эти два фрагмента кода эквивалентны. JSX — популярный синтаксис для описания разметки в JavaScript. Многие с ним знакомы и считают полезным для написания UI кода — как с React, так и с другими библиотеками.return <button onClick={() => setLiked(true)}>Like</button>;
Попробуйте JSX
Самый быстрый способ попробовать JSX — добавить на страницу компилятор Babel в теге<script>
. Поместите его перед like-button.js
, а затем в тег <script>
для like-button.js
добавьте атрибут type="text/babel"
:
Теперь вы можете открыть<script src="https://unpkg.com/react@18/umd/react.production.min.js" crossorigin></script> <script src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js" crossorigin></script> <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script> <script src="like-button.js" type="text/babel"></script> </body>
like-button.js
и заменить
на эквивалентный JSX код:return React.createElement( 'button', { onClick: () => setLiked(true), }, 'Like' );
Поначалу может показаться немного непривычным смешивать JS с разметкой, но вам это понравится. Ознакомьтесь со статьей Разметка с JSX. Компилятор Babel в тегеreturn <button onClick={() => setLiked(true)}>Like</button>;
<script>
отлично подходит для обучения и создания простых демо. Однако это замедляет ваш сайт и не подходит для продакшена. Когда вы будете готовы двигаться дальше, удалите тег <script>
с Babel и удалите атрибут type="text/babel"
. Вместо этого в следующем разделе мы настроим препроцессор JSX для преобразования всех тегов <script>
из JSX в JS.
Добавление JSX в проект
Добавление JSX в проект не требует сложных инструментов, таких как сборщик или сервер разработки. Добавление препроцессора JSX очень похоже на добавление препроцессора CSS. Перейдите в папку проекта в терминале и вставьте эти две команды (убедитесь, что у вас установлен Node.js):npm init -y
(if it fails, here’s a fix)npm install @babel/cli@7 babel-preset-react-app@10
npm init -y
, переименуйте папку проекта, чтобы она содержала только строчные буквы ASCII или дефисы (например, my-project
), и повторите попытку.
В данном случае npm будет нужен только для установки препроцессора JSX. И React, и код приложения могут оставаться в виде тегов <script>
без изменений.
Запуск препроцессора JSX
Вы можете предварительно обработать JSX, чтобы каждый раз, когда вы сохраняете файл с JSX, преобразование запускалось повторно, преобразовывая файл JSX в новый, простой файл JavaScript, который может понять браузер. Вот как это настроить:- Создайте папку с именем
src
. - В терминале выполните следующую команду:
Не ждите завершения. Эта команда запускает автоматическое наблюдение за изменениями в JSX внутриnpx babel --watch src --out-dir . --presets babel-preset-react-app/prod
src
.
- Переместите свой файл
like-button.js
c JSX в папкуsrc
.
like-button.js
с простым JavaScript кодом, подходящим для браузера.
Если вы видите сообщение об ошибке "You have mistakenly installed the babel package" ("Вы установили пакет babel по ошибке"), возможно, вы пропустили предыдущий шаг (Добавление JSX в проект). Выполните его в той же папке, а затем повторите попытку.
Инструмент, который вы только что использовали, называется Babel, и вы можете узнать больше о нем из его документации. В дополнение к JSX он позволяет вам использовать самые последние функции синтаксиса JavaScript, не беспокоясь о поломках в старых браузерах.
Если вы освоились с инструментами сборки и хотите, чтобы они делали для вас больше, то здесь вы можете найти обзор на некоторые из самых популярных и доступных наборов инструментов.
React без JSX
Первоначально JSX был представлен для того, чтобы написание компонентов с помощью React было таким же привычным, как написание HTML. С тех пор синтаксис получил широкое распространение. Однако могут быть случаи, когда вы не хотите или не можете использовать JSX. У вас есть два варианта:- Используйте альтернативу JSX, такую как htm, которая использует шаблонные строки JavaScript вместо компилятора.
- Используйте
React.createElement()
со специальной структурой, описанной ниже.
Сfunction Hello(props) { return <div>Hello {props.toWhat}</div>; } const root = ReactDOM.createRoot(document.getElementById('root')); root.render(<Hello toWhat="World" />);
React.createElement()
вы бы написали это так:
Он принимает несколько аргументов:function Hello(props) { return React.createElement('div', null, 'Hello ', props.toWhat); } const root = ReactDOM.createRoot(document.getElementById('root')); root.render(React.createElement(Hello, { toWhat: 'World' }, null));
React.createElement(component, props, ...children)
.
Вот как они работают:
- Компонент, который может быть строкой, представляющей элемент HTML или функциональный компонент.
- Объект с любыми пропсами, который вы хотите передать
- Остальные являются дочерними компонентами, такими как текстовые строки или другие элементы.
React.createElement()
, один из распространенных шаблонов — назначить сокращение:
Затем, если вы предпочитаете этот стиль, он может быть таким же удобным, как и JSX.const e = React.createElement; const root = ReactDOM.createRoot(document.getElementById('root')); root.render(e('div', null, 'Hello World'));
Вопросы и ответы React собеседования 2023 - Часть 2
год назад·6 мин. на чтение
Актуальный список вопросов и ответов по ReactJS на интервью 2023 - Часть 2
- Вопросы и ответы ReactJS собеседования 2023 - Часть 1
- Вопросы и ответы ReactJS собеседования 2023 - Часть 2 (эта статья)
- Вопросы и ответы ReactJS собеседования 2023 - Часть 3
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) из вашего приложения, а затем написать редьюсеры для этих действий, которые изменяют состояние.
- Весь переход состояния хранится внутри редьюсеров и не должен иметь никаких побочных эффектов.
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
в этом конкретном компоненте.
Подробности можно найти в статье Что за хук useId в React?.// Использование 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>);
10. Как проверить/валидировать пропсы в React?
Мы можем использовать пакетprop-types
Раньше, до React v15.5, это было частью самого React.
Еще один вариант - это добавить к проекту TypeScript.import PropTypes from "prop-types"; function MyComponent({ name }) { return <div>Hello, {name}</div>; } MyComponent.propTypes = { name: PropTypes.string, }; export default MyComponent;
11. Приведите практический пример компонента высшего порядка в React.
- Напишем компонент высшего порядка (HOC) для отображения загрузки, пока компонент ожидает данные.
- Больше о компонентах высшего порядка можно узнать в видео Как использовать Компоненты высшего порядка React и Паттерн Render Props в ReactJS.
// Компонент высшего порядка 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.
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> ); };