Шпаргалки по React, Jest, Redux и лучшие практики по React
Шпаргалка по React
Компоненты
import React from 'react'
import ReactDOM from 'react-dom'
class Hello extends React.Component {
render () {
return (
<div className='message-box'>
Привет, {this.props.name}
</div>
)
}
}
const el = document.body
ReactDOM.render(<Hello name='Иван' />, el)
Компоненты без состояния
// Компонент без состояния
const Headline = () => {
return <h1>Шапргалка по React</h1>
}
// Компонент, получающий пропы
const Greetings = (props) => {
return <p>Тебе это понравится, {props.name}.</p>
}
// Компонент должен возвращать единственный элемент
const Intro = () => {
return (
<div>
<Headline />
<p>Добро пожаловать в React!</p>
<Greetings name="Иван" />
</div>
)
}
ReactDOM.render(
<Intro />,
document.getElementById('root')
)
Пропы
<Video fullscreen={true} autoplay={false} />
render () {
this.props.fullscreen
// Используем `this.props` для доступа к пропам, переданным в компонент
const { fullscreen, autoplay } = this.props
}
Состояние
constructor(props) {
super(props)
this.state = { username: undefined }
}
this.setState({ username: 'Иван' })
render () {
this.state.username
// Используем `this.state` для управления динамическими данными
const { username } = this.state
}
Потомки/дети
<AlertBox>
<h1>У вас имеются непрочитанные сообщения</h1>
</AlertBox>
class AlertBox extends Component {
render () {
return (
// Потомки передаются в виде пропа `children`
<div className='alert-box'>
{this.props.children}
</div>
)
}
}
Вложенность
import React, { Component, Fragment } from 'react'
class Info extends Component {
render () {
const { avatar, username } = this.props
return (
<Fragment>
<UserAvatar src={avatar} />
<UserProfile username={username} />
</Fragment>
)
}
}
Функциональные компоненты
До появления хуков функциональные компоненты не могли иметь состояния. Они получали пропы от родительского компонента в качестве первого параметра.
function MyComponent ({ name }) {
return (
<div className='message-box'>
Привет, {name}
</div>
)
}
Чистые компоненты
Оптимизированная с точки зрения производительности версия React.Component
.
import React, { PureComponent } from 'react'
class MessageBox extends PureComponent {
···
}
Монтирование
Устанавливаем начальное состосние в constructor()
. Добавляем обработчики событий, таймеры и т.п. в componentDidMount()
, затем удаляем их в componentWillUnmount()
.
constructor (props) // Перед рендерингом
componentWillMount() // Не рекомендуется использовать
render() // Рендеринг
componentDidMount() // После рендеринга (DOM доступен)
componentWillUnmount() // Перед удалением из DOM
componentDidCatch() // Перехват ошибок
Обновление
Вызывается при изменении состояния или пропов. Не вызывается при первом рендеринге.
componentDidUpdate (prevProps, prevState, snapshot) // При использовании `setState()` не забывайте сравнивать пропы
shouldComponentUpdate (newProps, newState) // Если возвращается `false`, повторный рандеринг не выполняется
render() // Рендеринг
componentDidUpdate (prevProps, prevState) // Выполнение операций с DOM
Хук состояния
import React, { useState } from 'react'
function Example() {
// Хук `useState()` возвращает начальное состояние (`count`) и функцию для его обновления (`setCount`) - геттер и сеттер
const [count, setCount] = useState(0)
return (
<div>
<p>Вы нажали {count} раз</p>
<button onClick={() => setCount(count + 1)}>
Нажми на меня
</button>
</div>
)
}
Хук эффекта
Хук useEffect()
представлет собой сочетание методов жизненного цикла componentDidMount()
, componentDidUpdate()
и componentWillUnmount()
.
import React, { useState, useEffect } from 'react'
function Example() {
const [count, setCount] = useState(0)
// Аналогично `componentDidMount()` и `componentDidUpdate()`
useEffect(() => {
// Обновляем заголовок документа с помощью браузерного API
document.title = `Вы нажали ${count} раз`
}, [count])
return (
<div>
<p>Вы нажали {count} раз</p>
<button onClick={() => setCount(count + 1)}>
Нажми на меня
</button>
</div>
)
}
Ссылки/рефы
Позволяют получить доступ к узлам DOM.
class MyComponent extends Component {
render () {
return (
<div>
<input ref={el => this.input = el} />
</div>
)
}
componentDidMount () {
this.input.focus()
}
}
События
Передаем функции в атрибуты вроде onChange()
.
class MyComponent extends Component {
render () {
<input
type="text"
value={this.state.value}
onChange={event => this.onChange(event)}
/>
}
onChange (event) {
this.setState({ value: event.target.value })
}
}
Передача пропов
Передаем src="..."
в субкомпонент.
<VideoPlayer src="video.mp4" />
class VideoPlayer extends Component {
render () {
return <VideoEmbed {...this.props} />
}
}
Стилизация
Встроенные стили
const style = { height: 10 }
return <div style={style}></div>
return <div style={{ margin: 0, padding: 0 }}></div>
Условия
<Fragment>
{showMyComponent
? <MyComponent />
: <OtherComponent />}
</Fragment>
Списки
class TodoList extends Component {
render () {
const { items } = this.props
return <ul>
{items.map(item =>
<TodoItem item={item} key={item.key} />)}
</ul>
}
}
Короткие вычисления
<Fragment>
{showPopup && <Popup />}
...
</Fragment>
Фрагменты и массивы
// Массивы
render () {
// Не забывайте про ключи
return [
<li key="A">Первый элемент</li>,
<li key="B">Второй элемент</li>
]
}
// Фрагменты
render () {
// Фрагментам не нужны ключи
return (
<Fragment>
<li>Первый элемент</li>
<li>Второй элемент</li>
</Fragment>
)
}
Ошибки
Перехватываем ошибки в componentDidCatch()
.
class MyComponent extends Component {
···
componentDidCatch (error, info) {
this.setState({ error })
}
}
Порталы
Позволяют рендерить this.props.children
в любом узле DOM.
render () {
return React.createPortal(
this.props.children,
document.getElementById('menu')
)
}
Гидратация
Используем ReactDOM.hydrate()
вместо ReactDOM.render()
, если рендерим статическую разметку, полученную от сервера.
const el = document.getElementById('app')
ReactDOM.hydrate(<App />, el)
PropTypes
Проверка типов.
import PropTypes from 'prop-types'
Свойство | Описание |
---|---|
any | Что угодно |
string | Строка |
number | Число |
func | Функция |
bool | True или false |
oneOf(any) | Тип Enum |
oneOfType(type array) | Тип Union |
array | Массив |
arrayOf(…) | Массив типов |
object | Объект |
objectOf(…) | Объект типов |
instanceOf(…) | Экземлпяр |
shape(…) | Форма |
element | React-элемент |
node | Узел DOM |
(···).isRequired | Обязательный |