React — это библиотека JavaScript для создания пользовательских интерфейсов. Сегодня в статье рассмотрим руководство, предназначеное для React v15–v16.
1 2 3 4 5 |
import React from 'react' import ReactDOM from 'react-dom' |
1 2 3 4 5 6 7 8 9 10 |
class Hello extends React.Component { render () { return <div className='message-box'> Hello {this.props.name} </div> } } |
1 2 3 4 5 |
const el = document.body ReactDOM.render(<Hello name='John' />, el) |
Используйте jsfiddle React.js , чтобы начать взлом. (или неофициальный jsbin )
1 2 3 4 5 |
import React, {Component} from 'react' import ReactDOM from 'react-dom' |
1 2 3 4 5 6 |
class Hello extends Component { ... } |
1 2 3 4 |
<Video fullscreen={true} autoplay={false} /> |
1 2 3 4 5 6 7 8 |
render () { this.props.fullscreen const { fullscreen, autoplay } = this.props ··· } |
Используйте this.props
для доступа к свойствам, переданным компоненту.
См.: Свойства
1 2 3 4 5 6 7 |
constructor(props) { super(props) this.state = { username: undefined } } |
1 2 3 4 |
this.setState({ username: 'rstacruz' }) |
1 2 3 4 5 6 7 8 |
render () { this.state.username const { username } = this.state ··· } |
Используйте состояния ( this.state
) для управления динамическими данными.
С Babel вы можете использовать поля класса предложений и избавиться от конструктора
1 2 3 4 5 6 7 |
class Hello extends Component { state = { username: undefined }; ... } |
См.: Штаты
Посмотреть книгу: Оптимизированные по производительности приложения React
1 2 3 4 5 6 7 8 9 10 11 12 13 |
class Info extends Component { render () { const { avatar, username } = this.props return <div> <UserAvatar src={avatar} /> <UserProfile username={username} /> </div> } } |
Начиная с React v16.2.0, фрагменты можно использовать для возврата нескольких дочерних элементов без добавления дополнительных узлов-оболочек в DOM.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
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> ) } } |
Компоненты гнезда для разделения задач.
1 2 3 4 5 6 |
<AlertBox> <h1>You have pending notifications</h1> </AlertBox> |
1 2 3 4 5 6 7 8 9 10 |
class AlertBox extends Component { render () { return <div className='alert-box'> {this.props.children} </div> } } |
Children передаются как children
собственность.
1 2 3 4 5 6 |
Hello.defaultProps = { color: 'blue' } |
См.: defaultProps
1 2 3 4 5 6 7 8 9 |
class Hello extends Component { constructor (props) { super(props) this.state = { visible: true } } } |
Установите состояние по умолчанию в файле constructor()
.
И без конструктора, использующего Babel с полем класса предложения .
1 2 3 4 5 6 |
class Hello extends Component { state = { visible: true } } |
См.: Установка состояния по умолчанию
1 2 3 4 5 6 7 8 |
function MyComponent ({ name }) { return <div className='message-box'> Hello {name} </div> } |
Функциональные компоненты не имеют состояния. Кроме того, props
они передаются в качестве первого параметра функции.
См.: Компоненты функций и классов .
1 2 3 4 5 6 7 8 |
import React, {PureComponent} from 'react' class MessageBox extends PureComponent { ··· } |
Оптимизированная по производительности версия React.Component
. Не перерисовывается, если реквизит/состояние не изменились.
См.: Чистые компоненты .
1 2 3 4 |
this.forceUpdate() |
1 2 3 4 5 |
this.setState({ ... }) this.setState(state => { ... }) |
1 2 3 4 5 |
this.state this.props |
Эти методы и свойства доступны для Component
экземпляров.
Метод | Описание |
---|---|
constructor (реквизит) | Перед рендерингом # |
componentWillMount() | Не используйте этот # |
render() | Рендер # |
componentDidMount() | После рендеринга (доступен DOM) # |
— | — |
componentWillUnmount() | Перед удалением DOM # |
— | — |
componentDidCatch() | Отлов ошибок (16+) # |
Установите начальное состояние на constructor()
.
Добавьте обработчики событий DOM, таймеры (и т. д.) на componentDidMount()
, а затем удалите их на componentWillUnmount()
.
Метод | Описание |
---|---|
componentDidUpdate (prevProps, prevState, моментальный снимок) | Используйте setState() здесь, но не забудьте сравнить реквизит |
shouldComponentUpdate (новые реквизиты, новое состояние) | Пропускает render() , если возвращает false |
render() | Оказывать |
componentDidUpdate (предпропс, превстате) | Работайте с DOM здесь |
Вызывается, когда родители изменяют свойства и .setState()
. Они не вызываются для первоначальных рендеров.
См.: Спецификации компонентов .
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
import React, { useState } from 'react'; function Example() { // Declare a new state variable, which we'll call "count" const [count, setCount] = useState(0); return ( <div> <p>You clicked {count} times</p> <button onClick={() => setCount(count + 1)}> Click me </button> </div> ); } |
Хуки — это новое дополнение в React 16.8.
См.: Hooks at a Glance
1 2 3 4 5 6 7 8 9 10 |
function ExampleWithManyStates() { // Declare multiple state variables! const [age, setAge] = useState(42); const [fruit, setFruit] = useState('banana'); const [todos, setTodos] = useState([{ text: 'Learn Hooks' }]); // ... } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
import React, { useState, useEffect } from 'react'; function Example() { const [count, setCount] = useState(0); // Similar to componentDidMount and componentDidUpdate: useEffect(() => { // Update the document title using the browser API document.title = `You clicked ${count} times`; }, [count]); return ( <div> <p>You clicked {count} times</p> <button onClick={() => setCount(count + 1)}> Click me </button> </div> ); } |
Если вы знакомы с методами жизненного цикла класса React, вы можете думать о useEffect
Hook как о componentDidMount
, componentDidUpdate
и componentWillUnmount
вместе взятых.
По умолчанию React запускает эффекты после каждого рендеринга, включая первый рендеринг.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
import React, { useState, useEffect } from 'react'; function FriendStatus(props) { const [isOnline, setIsOnline] = useState(null); useEffect(() => { function handleStatusChange(status) { setIsOnline(status.isOnline); } ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange); return () => { ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange); }; }, [props.friend.id]); if (isOnline === null) { return 'Loading...'; } return isOnline ? 'Online' : 'Offline'; } |
Эффекты также могут опционально указывать, как «убирать» после них, возвращая функцию.
1 2 3 4 5 6 7 8 9 10 11 |
function FriendStatus(props) { const isOnline = useFriendStatus(props.friend.id); if (isOnline === null) { return 'Loading...'; } return isOnline ? 'Online' : 'Offline'; } |
См.: Создание собственных хуков
См. также: Часто задаваемые вопросы по хукам
Крюк | Описание |
---|---|
useState (начальное состояние) | |
useEffect (() => {…}) | |
useContext (МойКонтекст) | значение, возвращенное изReact.createContext |
Полная информация: основные крючки
Крюк | Описание |
---|---|
useReducer (редуктор, начальный аргумент, инициализация) | |
useCallback (() => {…}) | |
useMemo (() => {…}) | |
useRef (Первоначальный значение) | |
useImperativeHandle (ссылка, () => { … }) | |
useLayoutEffect | идентичен useEffect , но срабатывает синхронно после всех мутаций DOM |
useDebugValue (стоимость) | отображать метку для пользовательских хуков в React DevTools |
Полная информация: Дополнительные крючки
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
class MyComponent extends Component { render () { return <div> <input ref={el => this.input = el} /> </div> } componentDidMount () { this.input.focus() } } |
Разрешает доступ к узлам DOM.
См.: Refs и DOM.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
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 }) } } |
Передайте функции атрибутам, таким как onChange
.
См.: События
1 2 3 4 |
<VideoPlayer src="video.mp4" /> |
1 2 3 4 5 6 7 8 |
class VideoPlayer extends Component { render () { return <VideoEmbed {...this.props} /> } } |
Распространяется src="..."
на подкомпонент.
1 2 3 4 5 |
React.createClass({ ... }) React.isValidElement(c) |
1 2 3 4 5 |
ReactDOM.render(<Component />, domnode, [callback]) ReactDOM.unmountComponentAtNode(domnode) |
1 2 3 4 5 |
ReactDOMServer.renderToString(<Component />) ReactDOMServer.renderToStaticMarkup(<Component />) |
Их больше, но эти самые распространенные.
См. API верхнего уровня React .
1 2 3 4 5 |
const style = { height: 10 } return <div style={style}></div> |
1 2 3 4 |
return <div style={{ margin: 0, padding: 0 }}></div> |
См.: Встроенные стили .
1 2 3 4 5 |
function markdownify() { return "<p>...</p>"; } <div dangerouslySetInnerHTML={{__html: markdownify()}} /> |
См.: Опасно установить innerHTML
1 2 3 4 5 6 7 8 9 10 11 12 13 |
class TodoList extends Component { render () { const { items } = this.props return <ul> {items.map(item => <TodoItem item={item} key={item.key} />)} </ul> } } |
Всегда предлагайте key
недвижимость.
1 2 3 4 5 6 7 8 |
<Fragment> {showMyComponent ? <MyComponent /> : <OtherComponent />} </Fragment> |
1 2 3 4 5 6 7 |
<Fragment> {showPopup && <Popup />} ... </Fragment> |
Вы можете вернуть несколько элементов в виде массивов или фрагментов.
1 2 3 4 5 6 7 8 9 10 |
render () { // Don't forget the keys! return [ <li key="A">First item</li>, <li key="B">Second item</li> ] } |
1 2 3 4 5 6 7 8 9 10 11 12 |
render () { // Fragments don't require keys! return ( <Fragment> <li>First item</li> <li>Second item</li> </Fragment> ) } |
См.: Фрагменты и строки .
1 2 3 4 5 6 |
render() { return 'Look ma, no spans!'; } |
Вы можете вернуть только строку.
См.: Фрагменты и строки .
1 2 3 4 5 6 7 8 9 |
class MyComponent extends Component { ··· componentDidCatch (error, info) { this.setState({ error }) } } |
Отлов ошибок через componentDidCatch
. (Реакция 16+)
См.: Обработка ошибок в React 16 .
1 2 3 4 5 6 7 8 9 |
render () { return React.createPortal( this.props.children, document.getElementById('menu') ) } |
Это отображается this.props.children
в любом месте в DOM.
См.: Порталы
1 2 3 4 5 |
const el = document.getElementById('app') ReactDOM.hydrate(<App />, el) |
Используйте ReactDOM.hydrate
вместо использования ReactDOM.render
, если вы выполняете рендеринг поверх вывода ReactDOMServer .
См.: Увлажнение .
1 2 3 4 |
import PropTypes from 'prop-types' |
См.: Проверка типов с помощью PropTypes.
Ключ | Описание |
---|---|
any | Что-нибудь |
Ключ | Описание |
---|---|
string | |
number | |
func | Функция |
bool | Правда или ложь |
Ключ | Описание |
---|---|
oneOf (Любые) | Типы перечислений |
oneOfType (массив типов) | Союз |
Ключ | Описание |
---|---|
array | |
arrayOf (…) |
Ключ | Описание |
---|---|
object | |
objectOf (…) | Объект со значениями определенного типа |
instanceOf (…) | Экземпляр класса |
shape (…) |
Ключ | Описание |
---|---|
element | Реагировать элемент |
node | DOM-узел |
Ключ | Описание |
---|---|
(···).isRequired | Необходимый |
1 2 3 4 5 6 7 8 9 10 |
MyComponent.propTypes = { email: PropTypes.string, seats: PropTypes.number, callback: PropTypes.func, isClosed: PropTypes.bool, any: PropTypes.any } |
1 2 3 4 5 6 |
MyCo.propTypes = { name: PropTypes.string.isRequired } |
1 2 3 4 5 6 7 8 9 10 |
MyCo.propTypes = { // React element element: PropTypes.element, // num, string, element, or an array of those node: PropTypes.node } |
1 2 3 4 5 6 7 8 |
MyCo.propTypes = { direction: PropTypes.oneOf([ 'left', 'right' ]) } |
1 2 3 4 5 6 7 8 9 10 |
MyCo.propTypes = { list: PropTypes.array, ages: PropTypes.arrayOf(PropTypes.number), user: PropTypes.object, user: PropTypes.objectOf(PropTypes.number), message: PropTypes.instanceOf(Message) } |
1 2 3 4 5 6 7 8 9 |
MyCo.propTypes = { user: PropTypes.shape({ name: PropTypes.string, age: PropTypes.number }) } |
Используйте .array[Of]
, .object[Of]
, .instanceOf
, .shape
.
1 2 3 4 5 6 7 8 9 10 |
MyCo.propTypes = { customProp: (props, key, componentName) => { if (!/matchme/.test(props[key])) { return new Error('Validation failed!') } } } |
Пользуйтесь и практикуйтесь! Все получится!
Источник статьи: http://dev.to/