Вопросы по React. Версия 2
React
, React Router
, библиотеки для React-приложений
Что такое React
?
React
- это JavaScript-библиотека
, предназначенная для создания быстрых и интерактивных пользовательских интерфейсов (user interfaces, UI) для веб- и мобильных приложений. Это открытая (с открытым исходным кодом), основанная на компонентах, библиотека для фронтенда, отвечающая только за слой представления (view) приложения.
Основная задача React
- разработка быстрых пользовательских интерфейсов. В нем используется виртуальная объектная модель документа (virtual document object model (DOM) - программный интерфейс приложения (application programming interface (API)), для HTML
и XML-документов
. Он определяет логическую структуру документа, способы доступа к документу и управления им. Виртуальный DOM
- это JavaScript-объект
, что повышает производительность приложения. Виртуальный DOM
быстрее обычного (браузерного, реального или настоящего). Мы можем использовать React
как на стороне клиента, так и на стороне сервера, а также вместе с другими фреймворками. В нем используются компоненты и различные паттерны проектирования для работы с данными, что улучшает читаемость кода и облегчает поддержку больших приложений.
Как React
работает?
Разрабатывая клиентские приложения, команда разработчиков Facebook
осознала, что DOM
является медленным. Для того, чтобы сделать его быстрее, React
использует виртуальный DOM
, который, по сути, является представлением DOM-дерева
в JavaScript
. Когда возникает необходимость чтения или записи в DOM
, используется данное представление. Затем виртуальный DOM
пытается определить наиболее эффективный способ обновления реального DOM
.
В отличие от DOM-элементов
браузера, создание элементов в React
обходится гораздо дешевле (с точки зрения производительности). Виртуальный DOM
заботится об обновлении настоящего для полного совпадения с React-элементами
. Это объясняется тем, что JavaScript
очень быстрый, и хранение DOM-дерева
в виде объекта ускоряет мо дификацию последнего.
Что такое компонент?
Компоненты (components) - это основные строительные блоки любого React-приложения
. Как правило, приложение на React
состоит из множества компонентов. Проще говоря, компонент - это JavaScript-класс
или функция, опционально принимающие так называемые пропы (свойства, properties, props) и возвращающие элемент React
, описывающий, как должна выглядеть определенная часть UI
.
React-приложение
состоит из множества компонентов, каждый из которых отвечает за отрисовку (рендеринг, render) небольшой, переиспользуемой (reusable) части приложения. Компоненты могут вкладываться в другие компоненты, что обеспечивает возможность создания сложных приложений, состоящих из элементарных "кирпичиков" (это называется "композицией компонентов"). Также компоненты могут поддерживать внутреннее состояни е - например, компонент TabList
может хранить переменную, значением которой является открытая вкладка.
class Welcome extends React.Component {
render() {
return <h1>Привет, народ!</h1>
}
}
Назовите преимущества и ограничения React
Преимущества
- Использование виртуального
DOM
для определения того, какие частиUI
подверглись изменениям, и повторный рендеринг только этих частей в реальномDOM
существенно повышают производительность приложения. JSX
(JavaScript
иXML
) делает код компонентов/блоков более читаемым. Он отчетливо показывает, как компоненты связаны (скомбинированы) между собой.- Связывание данных в
React
предоставляет хорошие условия для создания динамичных приложений. - Быстрый рендеринг. Использование встроенных методов для минимизации количества операций с
DOM
помогает оптимизировать и ускорить процесс обновления компонентов. - Тестируемость.
React
предоставляет отличные встроенные инструменты для тестирования и отладки кода. - Дружелюбность по отношению к
SEO
(search engine optimization - поисковая оптимизация).React
предоставляет возможность рендеринга страниц на стороне сервера и регистрации обработчиков событий на стороне клиента: _React.renderToString()
вызывается на сервере; _React.render()
выз ывается на клиенте; _React
сохраняет разметку, сгенерированную на сервере, и добавляет к ней обработчики событий.
Ограничения
- Кривая обучения. Будучи библиотекой, а не полноценным фреймворком,
React
требует глубоких знаний по внедрениюUI
во фреймворкиMVC
(Model-View-Controller - Модель-Представление-Контроллер). - Одним из недостатков
React
также является ориентированность на слой представления. Для решения проблем "Представления" требуется поиск подходящей "Модели" и "Контроллера". - Разработка приложения без использования изоморфного подхода приводит к проблемам с индексацией приложения поисковыми роботами (речь идет о том, что одностраничные приложения (
SPA
) индексируются хуже статических).
Что такое JSX
и как он помогает разрабатывать приложения?
JSX
позволяет создавать HTML-элементы
прямо в JavaScript
и помещать их в DOM
без использования таких методов, как createElement
или appendChild
. JSX
преобразует HTML-теги
в элементы React
. React
использует JSX
для шаблонизации вместо обычного JavaScript
. Использовать JSX
не обязательно, однако он предоставляет несколько преимуществ:
- Он быстрее благодаря оптимизации во время компиляции кода в
JavaScript
. - Он также является "типобезопасным", большинство ошибок перехватываются во время компиляции.
- Он позволяет легче и быстрее создавать шаблоны.
import React from 'react'
class App extends React.Component {
render() {
return (
<div>
Привет, народ!
</div>
)
}
}
export default App
JSX
- это выражения JavaScript
. JSX-выражения
являются валидными JavaScript-выражениями
. После компиляции, они становятся обычными объектами. Например, такой код:
const hello = <h1 className = "greet"> Привет, народ!</h1>
Компилируется в такой:
const hello = React.createElement {
type: "h1",
props: {
className: "greet",
children: "Привет, народ!"
}
}
Поскольку JSX
компилируется в объекты, он может использоваться наравне с обычными выражениями JavaScript
.
Что такое ReactDOM
?
ReactDOM
- это пакет (package), предоставляющий специфичные для браузера методы, которые могут быть использованы на верхнем уровне приложения для эффективного управления DOM-элементами
, имеющимися на странице. ReactDOM
предоставляет в распоряжение разработчиков следующие методы:
render
.findDOMNode
.unmountComponentAtNode
.hydrate
.createPortal
и др.
До версии 0.14
ReactDOM
был частью React
. Одной из главных причин разделения React
и ReactDOM
было появление React Native
. React
содержит функционал, используемый в веб- и мобильных приложениях. Функционал ReactDOM
используется только в веб-приложениях.
ReactDOM
использует наблюдаемые (observables
) объекты, которые предоставляют эффективный способ работы с DOM
. ReactDOM
может использоваться как на стороне клиента, так и на стороне сервера.
// index.js
import React from 'react'
import ReactDOM from 'react-dom'
import App from './App/App'
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
)
Для того, чтобы иметь возможность использовать ReactDOM
в веб-приложении, написанном на React
, мы, прежде всего, должны его импортировать из react-dom
:
import ReactDOM from 'react-dom'
ReactDOM.render()
Эта функция используется для рендеринга отдельного компонента React
или нескольких компонентов, обернутых в другой компонент, фрагмент (fragment) или контейнер div
. Данная функция использует эффективные методы React
для обновления DOM
, имея возможность обновлять только те части DOM
, которые подверглись изменениям. Функция возвращает ссылку на компонент или null
, если был отрендерен компонент без состояния.
ReactDOM.render()
удаляет всех потомков переданного контейнера, если таковые имеются. Он использует высокоэффективный алгоритм сравнения и способен модифицировать любое поддерево DOM
:
ReactDOM.render(element, container, callback)
- element:
JSX-выражение
илиReact-элемент
(компонент), который должен быть отрендерен; - container: контейнер (
HTML-элемент
), в котором должен быть отрисован компонент; - callback: опциональный параметр - функция, вызываемая после завершения рендеринга.
findDOMNode()
Эта функция, обычн о, используется для получения узла DOM
, в котором был отрендерен некоторый компонент. Данный метод используется редко, поскольку то же самое можно сделать с помощью атрибута ref
(ссылка, реф), добавленного к компоненту.
findDOMNode()
может быть реализован только в отношении смонтированных компонентов, поэтому функциональные компоненты не могут его использовать:
ReactDOM.findDOMNode(component)
Данный метод принимает один параметр - компонент, поиск которого осуществляется в DOM
. Функция возвращает DOM-узел
, в котором был отрисован компонент (в случае успеха) или null
.
unmountComponentAtNode()
Эта функция используется для размонтирования и удаления React-компонента
, который был отрендерен в определенном контейнере:
ReactDOM.unmountComponentAtNode(container)
Данный метод принимает единственный параметр - узел DOM
, из которого должен быть удален компонент. Функция возвращает true
в случае успеха, или false
в противном случае.
hydrate()
Эта функция эквивалентна методу render
, но используется при рендеринге на стороне сервера:
ReactDOM.hydrate(element, container, callback)
- element:
JSX-выражение
или компонентReact
, который должен быть отрендерен; - container: контейнер (
HTML-элемент
), в котором должен быть отрисован компонент; - callback: опциональный параметр - функция, вызываемая после завершения рендеринга.
Данная функция пытается зарегистрировать обработчики событий для существующей разметки и возвращает ссылку на компонент или null
в случае рендеринга компонента без состояния.
createPortal()
Обычно, когда элемент возвращается из метода render
компонента, он монтируется в DOM
как потомок ближайшего родительского узла, что в некоторых случаях является нежелательным. Порталы (portals) позволяют рендерить компонент в узле DOM
, который находится за пределами текущего дерева DOM
родительского компонента:
ReactDOM.createPortal(child, container)
- child:
JSX-выражение
илиReact-компонент
для рендеринга; - container: контейнер (
HTML-элемент
), в котором должен быть отрисован компонент.
В чем разница между ReactDOM
и React
?
import React from 'react'
import ReactDOM from 'react-dom'
class MyComponent extends React.Component {
render() {
return <div>Привет, народ!</div>
}
})
ReactDOM.render(<MyComponent />, someDomNode)
Пакет React
содержит такие методы, как React.createElement
, React.createClass
, React.Component
, React.Children
и т.д.
Пакет ReactDOM
содержит такие методы, как ReactDOM.render
, ReactDOM.unmountComponentAtNode
, ReactDOM.findDOMNode
, а также react-dom/server
, включающий методы ReactDOMServer.renderToString
и ReactDOMServer.renderToStaticMarkup
.
Модуль ReactDOM
содержит специфичные для DOM
методы, в то время как React
включает основные инструменты для разных платформ (например, React Native
).
В чем разница между классовыми и функциональными компонентами?
Функциональные компоненты
- Функциональные компоненты - это обычные функции
JavaScript
. Чаще всего, они представлены в форме стрелочных функций, но их вполне можно создавать и с помощью ключевого словаfunction
. - Их часто называют компонентами без состояния, которые просто принимают данные и отображают их в некоторой форме, поэтому они, в основном, отвечают за рендеринг
UI
(так было до появления хуков). - В них нельзя использовать методы жизненного цикла, например,
componentDidMount
(в настоящее время хуки предоставляют альтернативы почти всем методам жизненного цикла). - У них нет метода
render
. - Как правило, они отвечают за
UI
и форму представления данных (например, компонент кнопки). - Принимают и используют пропы.
- Им следует отдавать предпочтение в случаях, когда не требуется работать с состоянием (так было до появления хуков).
const ClockUsingHooks = props => {
const [time, setTime] = useState(new Date())
useEffect(() => {
const tick = setInterval(() => {
setTime(new Date())
}, 1000)
return () => { clearInterval(tick) }
}, [])
return (
<div className="clock">
<h1>Привет! Это часы, созданные с помощью функционального компонента</h1>
<h2>Сейчас {time.toLocaleTimeString()}</h2>
</div>
)
}
export default ClockUsingHooks
Классовые компоненты
- Для создания классовых компонентов используются классы
ES6
, расширяющие классReact.Component
. - Их часто называют компонентами с состоянием, поскольку в них реализуется логика поведения на основе некоторого состояния.
- Внутри классов могут использоваться методы жизненного цикла, например,
componentDidMount
. - Принимают
props
и имеют к ним доступ черезthis.props
. - Могут содержать
refs
(ссылки, рефы) на нижележащиеDOM-узлы
. - Могут использовать такие техники улучшения производительности, как
shouldComponentUpdate()
иPureComponent
class ClockUsingClass extends React.Component {
constructor(props) {
super(props)
this.state = { date: new Date() }
}
componentDidMount() {
this.time = setInterval(() => {
this.changeTime()
}, 1000)
}
componentWillUnmount() {
clearInterval(this.time)
}
changeTime() {
this.setState({ date: new Date() })
}
render() {
return (
<div className="clock">
<h1>Привет! Это часы, созданные с помощью классового компонента</h1>
<h2>Сейчас {this.state.date.toLocaleTimeString()}</h2>
</div>
)
}
}
export default ClockUsingClass