Руководство React для начинающих

rukovodstvo react dlya nachinayushhih

Содержание статьи

Заинтересованы изучением React? Получите мое руководство по React

React – это библиотека JavaScript, которая направлена ​​на упрощение разработки визуальных интерфейсов.

Разработанный в Facebook и выпущенный в 2013 году, он руководит одним из самых распространенных кодов в мире. Это мощность Facebook и Instagram среди многих, многих других компаний, занимающихся программным обеспечением.

Его главная цель – облегчить рассуждение об интерфейсе и его состоянии в любой момент времени путем разделения пользовательского интерфейса на набор компонентов.

React используется для создания одностраничных веб-приложений вместе со многими другими библиотеками и фреймворками, доступными для появления React.

React увлек мир внешней веб-разработки штурмом. почему

Менее сложный, чем альтернативы

В то время, когда были объявлены React, Ember.js и Angular 1.x были предпочтительным выбором для фреймворков. Оба они накладывали слишком много условностей на код, поэтому перенос существующей программы был совсем неудобным.

React создан для того, чтобы его было очень легко интегрировать в существующий проект. Именно так им пришлось сделать это на Facebook, чтобы представить его в существующую кодовую базу. Кроме того, эти два фреймворка принесли слишком много, тогда как React решил реализовать только уровень View вместо полного стека MVC.

Идеальное время

В то же время Google анонсировал Angular 2.x вместе с обратной несовместимостью и серьезными изменениями, которые он должен принести. Переход от Angular 1 к 2 походил на переход к другому фреймворку. И поэтому этот факт, а также улучшение скорости исполнения, которые обещал React, сделали React тем, что разработчики стремились попробовать.

Поддерживается Facebook

Поддержка Facebook приносит пользу проекту, если он оказывается успешным. Но это не гарантия, и существует много неудачных проектов с открытым кодом как Facebook, так и Google (в числе прочих).

Действительно ли React так прост?

Несмотря на то, что я сказал, что React проще альтернативных фреймворков, погружение в React все равно сложно. Это в основном через дополнительные технологии, которые можно интегрировать с React, например Redux, Relay или GraphQL.

React сам по себе имеет очень небольшой API.

У React нет ничего другого, кроме этих концепций:

Каждый из них мы увидим в следующих моих статьях.

JSX

Многие разработчики, включая меня, на первый взгляд подумали, что JSX ужасен, и быстро отвергли React.

Несмотря на то, что они сказали, что JSX не нужен, использование React без JSX было болезненным.

Мне понадобилось несколько лет время от времени рассматривать его, чтобы начать переваривать JSX, и теперь я в основном предпочитаю его альтернативе (т.е. использованием шаблонов).

Основное преимущество использования JSX состоит в том, что вы взаимодействуете только с объектами JavaScript, а не со строками шаблона.

JSX не является встроенным HTML.

Многие учебники для начинающих React любят откладывать внедрение JSX на потом, поскольку они предполагают, что читателю будет лучше без него. Однако поскольку я теперь фанат JSX, я немедленно перейду к нему.

Вот как вы определяете тэг h1, содержащий строку:

const element = <h1>Hello, world!</h1>

Это выглядит как удивительная смесь JavaScript и HTML, но на самом деле это все JavaScript.

То, что выглядит как HTML, является сладким синтаксисом для определения компонентов и их расположения в разметке.

В выражение JSX атрибуты можно вставить очень легко:

const myId = 'test' 
const element = <h1 id={myId}>Hello, world!</h1>

Вам просто нужно обратить внимание, когда атрибут имеет тире (-), который превращается в синтаксис верблюжьего регистра, а также в эти два специальных случая:

  • class становится className
  • for становится htmlFor

потому что это зарезервированные слова в JavaScript.

Вот фрагмент JSX, объединяющий два компонента в div тег:

<div> 
  <BlogPostsList />
  <Sidebar /> 
</div>

Тег всегда нужно закрывать, поскольку это больше XML чем HTML (если вы помните времена XHTML, это будет знакомо, но с тех пор свободный синтаксис HTML5 победил). В этом случае используется самозакрывающийся тег.

JSX, представленный вместе с React, больше не является технологией только React.

Компоненты React

Что такое компонент React?

Компонент – это один изолированный элемент интерфейса. Например, на типичной домашней странице блога вы можете найти компонент Боковая панель и компонент Список сообщений блога. Они, в свою очередь, состоят из самих компонентов, поэтому вы можете иметь список компонентов сообщения в блоге, каждый для каждого сообщения в блоге, и каждый со своими свойствами.

Ok51aJciCr9ybh8lww0UL2Hl7g37lC2MJjne

React делает это очень просто: все является компонентом.

Даже обычные HTML-теги являются компонентами самостоятельно, и они добавляются по умолчанию.

Следующие две строчки эквивалентны — они делают то же самое. Один из JSXодин без, введением <h1>Hello World!

в элементent с приложением идентификатора.

import React from 'react' 
import ReactDOM from 'react-dom' 

ReactDOM.render( 
  <h1>Hello World!</h1>, 
  document.getElementById('app') 
)

ReactDOM.render( 
  React.DOM.h1(null, "Hello World!"), 
  document.getElementById('app') 
)

Увидеть, React.DOM выставлены для нас ан h1 компонент. Какие еще доступны тэги HTML? Все! Вы можете проверить что React.DOM предлагает, введя его в консоли браузера:

9DaF1EtL86DXgUhe2wvb92sjYFLx6S5nxcIr

(список можно продолжать…)

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

Специальные компоненты

Существует 2 способа определения компонента в React:

Компонент без состояния не управляет внутренним состоянием и является только функцией:

const BlogPostExcerpt = () => {
 return (
    <div>
      <h1>Title</h1>
      <p>Description</p>
    </div> 
  ) 
}

Компонент с сохранением состояния – это класс, управляющий состоянием в собственных свойствах:

import React, { Component } from 'react'

class BlogPostExcerpt extends Component { 
  render() { 
    return ( 
      <div>
        <h1>Title</h1> 
        <p>Description</p> 
      </div> 
    ) 
  } 
}

В текущем состоянии они эквивалентны, поскольку государственного управления еще нет (об этом говорится в следующих статьях).

Существует третий синтаксис, использующий ES5 / ES2015 синтаксис без классов:

import React from 'react'

React.createClass({ 
  render() { 
    return ( 
      <div> 
        <h1>Title</h1>
        <p>Description</p> 
      </div> 
    ) 
  } 
})

Вы редко увидите такое в современности > ES6 кодовые базы

Props – это то, как компоненты получают свои свойства. Начиная с верхнего компонента каждый дочерний компонент получает свои свойства от родительского. В компоненте без состояния все передаваемое — это свойства, которые становятся доступными путем добавления props как аргумент функции:

const BlogPostExcerpt = (props) => { 
  return ( 
    <div> 
      <h1>{props.title}</h1> 
      <p>{props.description}</p> 
    </div> 
  ) 
}

В компоненте с сохранением состояния свойства передаются по умолчанию. Ничего особенного добавлять не нужно, и они доступны как this.props в экземпляре компонента.

import React, { Component } from 'react'

class BlogPostExcerpt extends Component { 
  render() { 
    return ( 
      <div>
        <h1>{this.props.title}</h1>  
        <p>{this.props.description}</p> 
      </div> 
    ) 
  } 
}

PropTypes

Поскольку JavaScript является динамически типизированным языком, мы не имеем способа обеспечить тип переменной во время компиляции. Если мы передаем недействительные типы, они не будут работать во время выполнения или дадут странные результаты, если типы совместимы, но не такие, как мы ожидаем.

Flow и TypeScript очень помогают, но React имеет способ напрямую помочь с типами пропсов. Еще до запуска кода наши инструменты (редакторы, линтеры) могут обнаружить, когда мы передаем неправильные значения:

import PropTypes from 'prop-types';
import React from 'react' 

class BlogPostExcerpt extends Component { 
  render() { 
    return ( 
      <div> 
        <h1>{this.props.title}</h1> 
        <p>{this.props.description}</p> 
      </div> 
    ) 
  } 
}

BlogPostExcerpt.propTypes = { 
  title: PropTypes.string, 
  description: PropTypes.string 
};

export default BlogPostExcerpt

Какие типы мы можем использовать

Вот основные типы, которые мы можем принять:

  • PropTypes.array
  • PropTypes.bool
  • PropTypes.func
  • PropTypes.number
  • PropTypes.object
  • PropTypes.string
  • PropTypes.symbol

Мы можем принять один из двух типов:

PropTypes.oneOfType([ PropTypes.string, PropTypes.number ]),

Мы можем принять одно из многих значений:

PropTypes.oneOf(['Test1', 'Test2']),

Мы можем принять экземпляр класса:

PropTypes.instanceOf(Something)

Мы можем принять любой узел React:

PropTypes.node

или даже любой тип вообще:

PropTypes.any

Массивы имеют специальный синтаксис, который можно использовать для принятия массива определенного типа:

PropTypes.arrayOf(PropTypes.string)

Мы можем создать свойство объекта, используя:

PropTypes.shape({ 
  color: PropTypes.string, 
  fontSize: PropTypes.number 
})

Необходимые свойства

Добавление isRequired к любой опции PropTypes приведет к тому, что React вернет ошибку, если это свойство отсутствует:

PropTypes.arrayOf(PropTypes.string).isRequired, PropTypes.string.isRequired,

Значение по умолчанию для реквизитов

Если какое-либо значение не требуется, нам нужно указать для него значение по умолчанию, если оно отсутствует при инициализации Компонента.

BlogPostExcerpt.propTypes = { 
  title: PropTypes.string, 
  description: PropTypes.string 
}

BlogPostExcerpt.defaultProps = { 
  title: '', 
  description: '' 
}

Некоторые инструменты, такие как ESLint, могут принудительно определять defaultProps для компонента с некоторыми propTypes, которые явно не нужны.

Как передается реквизит

При инициализации компонента передайте свойства подобно атрибутам HTML:

const desc="A description" 
//... 
<BlogPostExcerpt title="A blog post" description={desc} />

Мы передали название как простая строка (то, что мы можем только делать со строками!), а описание как переменную.

дети

Специальный реквизит есть children. Он содержит значение всего, что передается в body компонента Например:

<BlogPostExcerpt title="A blog post" description={desc}> 
  Something 
</BlogPostExcerpt>

В данном случае внутри BlogPostExcerpt мы могли получить доступ к «Что-то», посмотрев вверх this.props.children.

В то время как Props позволяет компоненту получать свойства от своего родителя (им можно «поручить» напечатать некоторые данные, например), состояние позволяет компоненту жить собственной жизнью и быть независимым от окружающей среды.

Помните, что только компоненты на основе класса могут иметь состояние. Итак, если вам нужно управлять состоянием в компоненте без состояния (на основе функции), вам сначала нужно «обновить» его в компонент класса:

const BlogPostExcerpt = () => { 
  return ( 
    <div>
      <h1>Title</h1>
      <p>Description</p> 
    </div> 
  )
}

становится:

import React, { Component } from 'react'

class BlogPostExcerpt extends Component { 
  render() { 
    return (
      <div>  
        <h1>Title</h1> 
        <p>Description</p>
      </div>
    ) 
  } 
}

Установка стандартного состояния

В конструкторе Component выполните инициализацию this.state. Например, компонент BlogPostExcerpt может иметь a clicked состояние:

class BlogPostExcerpt extends Component {
  constructor(props) { 
    super(props) 
    this.state = { clicked: false } 
  }

  render() { 
    return (
      <div> 
        <h1>Title</h1>
        <p>Description</p> 
      </div> 
    ) 
  } 
}

Доступ к гос

The щелкнул состояние можно получить с помощью ссылки this.state.clicked:

class BlogPostExcerpt extends Component {
  constructor(props) { 
    super(props)
    this.state = { clicked: false }
  }

  render() { 
    return (
      <div> 
        <h1>Title</h1> 
        <p>Description</p> 
        <p>Clicked: {this.state.clicked}</p> 
      </div> 
    ) 
  } 
}

Мутация состояния

Состояние никогда нельзя изменять с помощью

this.state.clicked = true

Вместо этого вы всегда должны использовать setState() вместо этого передавая его как объект:

this.setState({ clicked: true })

Объект может содержать подмножество или сверхмножественное состояние. Изменяются только свойства, которые вы передаете. Пропущенные будут оставлены в текущем состоянии.

Почему вы всегда должны использовать setState()

Причина в том, что, используя этот метод, React знает, что состояние изменилось. Затем начнется серия событий, которые приведут к повторному рендерингу Компонента вместе с любыми обновлениями DOM.

Состояние инкапсулированное

Родительский компонент компонента не может определить, есть ли дочерний элемент со статусом или без состояния. То же касается детей компонента.

Быть состоянием или без состояния (функциональным или на основе класса) полностью деталью реализации, о которой другим компонентам не нужно заботиться.

Это ведет нас к однонаправленному потоку данных

Однонаправленный поток данных

Состояние всегда принадлежит одному компоненту. Любые данные, влияющие на это состояние, могут влиять только на Компоненты под ним: его дочерние элементы.

Изменение состояния Компонента никогда не повлияет на его родительский компонент, его братьев и сестер или любой другой Компонент в программе только на его дочерних компонентах.

Это причина того, что много раз состояние перемещается вверх в дереве компонентов.

Перемещение состояния вверх в дереве

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

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

Состояние передается компонентам, которым это значение нужно, через свойства:

class Converter extends React.Component { 
  constructor(props) { 
    super(props)
    this.state = { currency: '€' } 
  }

  render() { 
    return ( 
      <div> 
        <Display currency={this.state.currency} />
        <CurrencySwitcher currency={this.state.currency} />
      </div> 
    ) 
  } 
}

Состояние может быть изменено дочерним компонентом, передав мутирующую функцию вниз как проп:

class Converter extends React.Component { 
  constructor(props) { 
    super(props) 
    this.state = { currency: '€' } 
  }

  handleChangeCurrency = (event) => { 
    this.setState({ 
      currency: this.state.currency === '€' ? '$' : '€' 
    }) 
  }

  render() { 
    return ( 
      <div> 
        <Display currency={this.state.currency} /> 
        <CurrencySwitcher currency={this.state.currency} handleChangeCurrency={this.handleChangeCurrency} /> 
      </div> 
    ) 
  } 
}

const CurrencySwitcher = (props) => { 
  return ( 
    <button onClick={props.handleChangeCurrency}> 
      Current currency is {props.currency}. Change it! 
    </button> 
  ) 
}

const Display = (props) => { 
  return ( 
    <p>Current currency is {props.currency}.</p> 
  ) 
}
W5hfnSrCoSOqkbTNbDn0b1bOocYiHkO70ZgB

События

React обеспечивает простой способ управления событиями. Приготовьтесь попрощаться с addEventListener 🙂

В предыдущей статье о государстве вы видели этот пример:

const CurrencySwitcher = (props) => { 
  return ( 
    <button onClick={props.handleChangeCurrency}> 
      Current currency is {props.currency}. Change it! 
    </button> 
  ) 
}

Если вы используете JavaScript, это как обычные старые обработчики событий JavaScript. Но на этот раз вы определяете все в JavaScript, а не в своем HTML, и вы передаете функцию, а не строчку.

Фактические названия событий несколько отличаются, потому что в React вы используете camelCase для всего. Поэтому onclick становится onClick, onsubmit становится onSubmit.

Для справки, это старый школьный HTML с добавлением событий JavaScript:

<button onclick="handleChangeCurrency()"> ... <;/button>

Обработчики событий

Обработчики событий определены как методы в классе компонентов:

class Converter extends React.Component { handleChangeCurrency = (event) => { this.setState({ currency: this.state.currency === '€' ? '$' : '€' }) } }

Все обработчики получают объект события, который придерживается кроссбраузерной спецификации W3C UI Events.

Связать this в методах

Не забудьте связать способы. Методы классов ES6 по умолчанию не привязаны. Это означает, что this не определено, если вы не определите методы как

class Converter extends React.Component { 
  handleClick = (e) => { /* ... */ } 
  //... 
}

при использовании синтаксиса инициализатора свойства из Babel (включено по умолчанию в create-react-app).

В противном случае вам нужно привязать его вручную в конструкторе:

class Converter extends React.Component { 
  constructor(props) { 
    super(props); 
    this.handleClick = this.handleClick.bind(this); 
  }

  handleClick(e) {} 
}

Справка о событиях

Поддерживается много событий, потому вот краткий список.

Буфер обмена

Композиция

  • onCompositionEnd
  • onCompositionStart
  • onCompositionUpdate

Клавиатура

  • onKeyDown
  • onKeyPress
  • onKeyUp

Фокус

Форма

мышь

  • onClick
  • onContextMenu
  • onDoubleClick
  • onDrag
  • onDragEnd
  • onDragEnter
  • onDragExit
  • onDragLeave
  • onDragOver
  • onDragStart
  • onDrop
  • onMouseDown
  • onMouseEnter
  • onMouseLeave
  • onMouseMove
  • onMouseOut
  • onMouseOver
  • onMouseUp

Выбор

Прикосновение

  • onTouchCancel
  • onTouchEnd
  • onTouchMove
  • onTouchStart

интерфейс пользователя

Колесо мыши

СМИ

  • onAbort
  • onCanPlay
  • onCanPlayThrough
  • onDurationChange
  • onEmptied
  • onEncrypted
  • onEnded
  • onError
  • onLoadedData
  • onLoadedMetadata
  • onLoadStart
  • onPause
  • onPlay
  • onPlaying
  • в прогрессе
  • onRateChange
  • onSeeked
  • onSeeking
  • onStalled
  • onSuspend
  • onTimeUpdate
  • onVolumeChange
  • onWaiting

Изображение

Анимация

  • onAnimationStart
  • onAnimationEnd
  • onAnimationIteration

Переход

Декларативный подход React

Вы натолкнетесь на статьи, описывающие React как декларативный подход к построению UI.

Смотрите декларативное программирование, чтобы узнать больше о декларативном программировании.

Декларативный подход React

React сделал свой «декларативный подход» достаточно популярным и открытым, поэтому он проник в мир интерфейса вместе с React.

Это на самом деле не новая концепция, но React сделал создание пользовательских интерфейсов гораздо более декларативным, чем с помощью шаблонов HTML. Вы можете создавать веб-интерфейсы, даже не касаясь непосредственно DOM и вы можете иметь систему событий без взаимодействия с фактическими событиями DOM.

Например, поиск элементов в DOM с помощью jQuery или событий DOM является итеративным подходом.

Декларативный подход React отвлекает это для нас. Мы просто сообщаем React, что хотим, чтобы компонент воспроизводился определенным образом, и нам никогда не нужно взаимодействовать с DOM, чтобы ссылаться на него позже.

Виртуальный DOM

Многие существующие фреймворки до появления React непосредственно манипулировали DOM во время каждой смены.

«Настоящий» DOM

Что такое DOM, прежде всего? DOM (Объектная модель документа) является представлением дерева страницы, начиная с <html> тег, спускаемый к каждому из дочерних элементов, называемых узлами.

Он хранится в памяти браузера и напрямую связан с тем, что вы видите на странице. В DOM есть API, с помощью которого вы можете проходить через него, получать доступ к каждому отдельному узлу, фильтровать и изменять.

API – это знакомый синтаксис, который вы, вероятно, видели много раз, если бы вы не использовали абстрактный API, предоставленный jQuery и друзьями:

document.getElementById(id) 
document.getElementsByTagName(name) 
document.createElement(name) 
parentNode.appendChild(node) 
element.innerHTML 
element.style.left 
element.setAttribute()
element.getAttribute() 
element.addEventListener() 
window.content 
window.onload 
window.dump()
window.scrollTo()

React сохраняет копию представления DOM, потому что Virtual DOM касается визуализации React.

Виртуальный DOM

Каждый раз, когда DOM меняется, браузеру приходится выполнять две интенсивные операции: перерисовывать (визуальные изменения или изменения содержимого элемента, не влияющие на макет и позиционирование относительно других элементов) и перекомпоновать (перечислять макет части страницы или весь макет страницы).

React использует Virtual DOM, чтобы помочь браузеру использовать меньше ресурсов, когда на странице нужно внести изменения.

Когда звонишь setState() на компоненте, указывая состояние, отличное от предыдущего, React обозначает этот компонент как грязный. Это ключ: React обновляется только тогда, когда компонент явно изменяет состояние.

Далее происходит:

  • React обновляет Virtual DOM относительно компонентов, обозначенных как грязные (с некоторыми дополнительными проверками, например активация shouldComponentUpdate())
  • Запускает алгоритм разрешения для согласования изменений
  • Обновляет настоящий DOM

Почему виртуальный DOM полезен: пакетирование

Ключевым является то, что React группирует большинство изменений и выполняет уникальное обновление настоящего DOM. Он делает это, изменяя все элементы, которые нужно изменить одновременно, поэтому перекраска и перекомпоновка, которые должен просмотреть браузер, чтобы отобразить изменения, выполняются только один раз.

Заинтересованы изучением React? Получите мое руководство по React

Добавить комментарий

Ваш адрес email не будет опубликован.