Полезные ссылки
Дополнительные библиотеки
- classnames - A simple JavaScript utility for conditionally joining classNames together. ( yarn add classnames )
Create-React-App
npm i -g create-react-app
npm
npm init react-app my-app
Yarn
yarn create react-app my-app
npm start - запуск приложения
npm run eject
При возникновении ошибки react-scripts: command not found :
yarn upgrade
yarn
yarn run start
Концепции React JS
-
virtual DOM
-
компонентная разработка
-
jsx - способ описать html-вёрстку в js
Основные способы создания компоненты
- Расширить класс Component
class HelloWorld extends React.Component {
render() {
return <div>Hello!</div>;
}
}
- Расширить класс PureComponent
class HelloWorld extends React.PureComponent {
render() {
return <div>Hello!</div>;
}
}
- Написать функцию возвращающую jsx
function HelloWorld () {
return <div>Hello!</div>
}
Компоненты получают данные через props - атрибуты тега компоненты:
class Comment extends Component {
render() {
const {author, text} = props;
return (
<div>
<h4>{author}</h4>
<p>{text}</p>
</div>
);
}
}
class CommentList extends Component {
render() {
const comments = [
{text: 'hello!', author: 'Bill'},
{text: 'How are you?', author: 'Mary'}
];
return (
<ul>
{comments.map(comment => {
return <Comment author={comment.author} text={comment.text} />;
})}
</ul>
);
}
}
Состояние компоненты - this.state - Передать объект
```javascript
this.setState({a: 1})
```
-
Передать функцию
javascript this.setState(state => ({...state, a: 1}))
Функциональный компонент (созданных лишь одной функцией) - нет состояния и функций жизненного цикла.
Потомки тегов
props.children - для работы с детьми тегов.
Для работы со списками детей у реакта есть функция помощник React.Children.map, и если вы хотите обернуть каждого ребенка в дополнительный тег:
const Parent = props => (
<div>
<p>Parent</p>
{React.Children.map(props.children, child => <p>{child}</p>)}
</div>
);
Порядок вызовов методов компоненты
Монтирование компоненты
-
constructor
-
componentWillMount
-
render
-
componentDidMount
Обновление компоненты
-
compoentWillReceiveProps
-
shouldComponentUpdate
-
componentWillUpdate
-
render
-
componentDidUpdate
Удаление компоненты
-
componentWillUnmoun
-
forceUpdate()
По умолчанию, компонент вызывает метод render только если он получает новые props, меняет state или монтируется. Есть возможность вызвать в ручную метод render, с помощью forceUpdate. В нормальной ситуации не стоит вызывать метод, а когда покажется что стоит, нужно подумать еще 7 раз.
- defaultProps
Это переменная класса, для того чтобы задать props по-умолчанию. Желательно задать все props, от которых зависит render компоненты.
- displayName
Это переменная класса нужна только при разработке и дебагинге. Помогает увидеть, где точно произошла ошибка в стеке ошибок.
События в React
Для работы с событиями, поступающими от тега или компонента, необходимо использовать атрибут компонента onChange.
class Form extends React.Component {
state = {
value: ''
};
handleOnChange = event => {
this.setState({value: event.target.value});
};
render() {
return (
<div>
<p>{this.state.value}</p>
<input value={this.state.value} onChange={this.handleOnChange} />
</div>
);
}
}
Cуществуют методы onInput для получения событий input, onSubmit для тегов form, onClick, onFocus для событий получения фокуса и onBlur для событий удаления фокуса.
Cписок обработчиков событий для мышки:
onClick, onContextMenu, onDoubleClick, onDrag, onDragEnd, onDragEnter, onDragExit, onDragLeave, onDragOver, onDragStart, onDrop, onMouseDown, onMouseEnter, onMouseLeave, onMouseMove, onMouseOut, onMouseOver, onMouseUp.
Все обработчики событий получают синтетическое событие, если нужно остановить баблинг события, можно воспользоваться event.preventDefault() иди event.stopPropagation().
Если нужно передать событие, и воспользоваться им в асинхронном коде, в следующих тиках — необходимо вызвать метод event.persist() чтобы реакт отдал вам это событие.
Проверка типов PropTypes
Для установки нужно выполнить команду:
yarn add prop-types
Чтобы перечислить типы параметров компоненты:
- Добавить параметр propTypes к уже созданному классу или функции:
import PropTypes from 'prop-types';
import React from 'react';
const Greeting = ({name}) =>
<p>Hi, {name}!</p>
Greeting.propTypes = {
name: PropTypes.string,
name2: PropTypes.string.isRequired // isRequired указывает что переменная обязательно
}
- Для классов можно объявить статическую внутреннюю переменную propTypes для того, чтобы объявлять необходимые типы прямо в компоненте:
```javascript import PropTypes from 'prop-types'; import React from 'react';
class UserCard extends React.Component { static propTypes = { user: PropTypes.shape({ firstName: PropTypes.string.isRequired, lastName: PropTypes.string.isRequired, email: PropTypes.string.isRequired }).isRequired, isAdmin: PropTypes.boolean.isRequired };
defaultProps = { isAdmin: false };
render() { return ... } } ```
Если указаны значения в defaultProps, а компонента не получила значений от родителя для PropTypes с флагом isRequired,значение будет взято из defaultProps.
Список типов, которые доступны в PropTypes:
MyComponent.propTypes = {
// Все PropTypes опциональны, и делают проверку только на соответствие типа
optionalArray: PropTypes.array,
optionalBool: PropTypes.bool,
optionalFunc: PropTypes.func,
optionalNumber: PropTypes.number,
optionalObject: PropTypes.object,
optionalString: PropTypes.string,
optionalSymbol: PropTypes.symbol,
// Этот тип описывает любой элемент, который реакт может отрендерить в jsx
optionalNode: PropTypes.node,
// Реакт компонент
optionalElement: PropTypes.element,
// Также можно проверить, является ли тип экземпляром конкретного класса
optionalMessage: PropTypes.instanceOf(Message),
// Позволяет проверить, что значение является одним из списка
optionalEnum: PropTypes.oneOf(['News', 'Photos']),
// Переменная может быть одной из перечисленных типов
optionalUnion: PropTypes.oneOfType([
PropTypes.string,
PropTypes.instanceOf(Message)
]),
// Переменная должна быть списком элементов с конкретным типом
optionalArrayOf: PropTypes.arrayOf(PropTypes.number),
// Объект должен содержать значения определенного типа
optionalObjectOf: PropTypes.objectOf(PropTypes.number),
// Проверка ключей объекта на соответствие типа
optionalObjectWithShape: PropTypes.shape({
color: PropTypes.string,
fontSize: PropTypes.number
}),
// Пометить переменную, как обязательную
requiredFunc: PropTypes.func.isRequired,
// Переменная может быть любого типа
requiredAny: PropTypes.any.isRequired
};
Порталы
Когда нужно отрендерить компонент не в текущем месте дерева компонент, а отдельно, например, модальные окна, тултипы, попапы. Такого рода элементы находятся в самом конце тега body, чтобы быть выше остальных элементов.
В случае порталов, нам необходимо вернуть ReactDOM.createPortal:
class ModalWindow extends Component {
render() {
return ReactDOM.createPortal(this.props.children, this.props.domNode);
}
}
class App extends Component {
render() {
return (
<ModalWindow domNode={document.querySelector('#modal')}>
<p>It is modal window</p>
</ModalWindow>
);
}
}
Первый аргумент - компонент реакта; Вторым — DOM объект, в котором реакт разместит этот компонент.
Сcылки ref
Существует несколько оправданных случаев использования ссылок ref:
-
Управление фокусом, выделением текста или воспроизведением мультимедиа
-
Переключение необходимой анимации
-
Интеграция со сторонними DOM библиотеками
Избегайте использования ссылок для всего, что может быть реализовано декларативным путем!
React-роутинг (динамический роутинг) установка
yarn add react-router-dom
Также существует пакет react-router-native для работы на мобильных устройствах вместе с react-native, и react-router, который содержит общий код для этих библиотек.
Также существует пакет react-router-native для работы на мобильных устройствах вместе с react-native, и react-router, который содержит общий код для этих библиотек.
Обернуть корневой компонент с помощью BrowserRouter: import {BrowserRouter} from 'react-router-dom';
ReactDOM.render(
<BrowserRouter>
<App />
</BrowserRouter>,
document.getElementById('root')
);
Вот и реализация роутинга:
import React from 'react';
import {Link, Route} from 'react-router-dom';
const Home = () => <p>Home page</p>;
const About = () => <p>About page</p>;
const Topics = () => <p>Topics page</p>;
const App = () => (
<div>
<ul>
<li><Link to="/">Home</Link></li>
<li><Link to="/about">About</Link></li>
<li><Link to="/topics">Topics</Link></li>
</ul>
<hr />
<Route exact path="/" component={Home} />
<Route path="/about" component={About} />
<Route path="/topics" component={Topics} />
</div>
);
export default App;
Для работы с переходами по страницам используется компонента Link, которая превращается в тег a, но реакт-роутер обрабатывает переход так, чтобы не было перезагрузки страницы. Роутер ловит событие клика на ссылку, отменят его, и делает push в window.history, браузер переходит на новый путь без перезагрузки страницы.
Компоненты, которые возвращает компонент Route получают в props дополнительный параметры:
match = {
isExact: true,
params: {},
path: '/topics',
url: '/topics'
}
location = {
hash: "",
pathname: "/topics",
search: "",
state: {}
}
-
Match содержит данные по соответствию пути и роута и дополнительные параметры.
-
IsExact говорит о том, что путь в браузерной строке полностью соответствует роуту.
-
В params находятся дополнительные ключи, которые можно спарсить из роута, если путь использует регулярное выражение или /topics/:id.
-
Path — это путь с которым проводили сравнение. Полезен для создания вложенных Route.
-
Url — это полный путь, полезен для создания вложенных Link.
History — это объект, который использует библиотеку history (https://github.com/ReactTraining/history) для удобной работы с сессией и историей переходов. Также реакт-роутер может работать с якорными переходами, когда url меняется не целиком, а только после якоря #
-
length — длина истории, количество location в стеке истории.
-
action — текущее действие, выполненное с историей: PUSH, REPLACE или POP. Соответствует переходу на страницу, замене текущей страницы и переходу назад.
-
location — текущая локация, соответствует location, переданному отдельно через prop.
-
push — функция, с помощью которой происходит переход по истории.
-
replace — функция для замены текущего пути.
-
go(n) — функция для указания номера пути в стеке истории путей.
-
goBack — функция для перехода назад (go(-1)).
-
goForward — функция для перехода вперед(go(1)).
-
block(promt) — функция для остановки перехода пользователя, которая вызовет окно confirm с просьбой не покидать страницу ("Вы уверены что хотите закрыть страницу?").
компонент Switch и редиректы
<Switch>
<Route path="/" exact component={Home} />
<Redirect from="/old-match" to="/will-match" />
<Route path="/will-match" component={WillMatch} />
<Route component={NoMatch} />
</Switch>;
Компонент Switch последовательно смотрит детей и сравнивает их path и флаги exact и strict.