Skip to content
This repository has been archived by the owner on Sep 15, 2022. It is now read-only.

Latest commit

 

History

History

02-deep-in-components

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 

Урок 2 — Компоненты

мини-тест по содержанию урока (5 минут)

Примеры из видео

Резюме

В предыдущем уроке мы научились писать несложные компоненты на React, использовать props и state компонентов, обрабатывать события и компоновать компоненты на странице. В данном уроке мы узнаем еще больше о компонентах, изучим их жизненный цикл, научимся использовать refs, работать с дочерними компонентами и DOM.

Жизненный цикл компонентов в React

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

Есть всего 4 сценария, когда методы жизненного цикла могут быть использованы:

  1. Инициализация компонента
  2. Изменение его параметров (props)
  3. Изменение его состояния (вызов setState)
  4. Удаление компонента

Инициализация компонента (первый render)

При первом render компонента методы жизненного цикла будут вызваны в таком порядке:

Инициализация компонента (первый render)

Изменение параметров (props)

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

Изменение параметров

Изменение состояния (вызов setState)

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

Изменение состояния

Удаление компонента

Перед удаление компонента из DOM будет вызван один-единственный метод сomponentWillUnmount

Удаление компонента

Методы жизненного цикла

getDefaultProps

Вызывается единожды при инициализации класса. Отвечает за значения параметров по умолчанию.

getDefaultProps: function() {
    return {
        name: ‘’,
        age: 0
    };
}

getInitialState

Создан для определения начального состояния компонента.

getInitialState: function() {
    return {
        isOpened: true
    };
}

componentWillMount

Вызывается один раз прямо перед тем, как состоится первый render компонента. Вызов setState в рамках данного метода дополнительного рендера не вызовет.

componentWillMount: function() {
    // ...
}

componentDidMount

Вызывается один раз прямо сразу после того, как состоялся первый render компонента.

componentDidMount: function() {
    // компонент уже находится в DOM
    // здесь можно уже взаимодействовать с DOM напрямую
    // например, использовать jQuery или какие-то сторонние библиотеки
}

componentWillReceiveProps

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

componentWillReceiveProps: function(nextProps) {
    // в nextProps содержится объект с новыми параметрами
    // старые параметры можно получить использование this.props
    this.setState({
        likesIncreasing: nextProps.likeCount > this.props.likeCount
    });
}

shouldComponentUpdate

Вызывается при изменении параметров или состояния. Возвращает true (если изменение должно вызвать перерисовку компонента) или false (если изменение не влияет на отображение компонента).

shouldComponentUpdate: function(nextProps, nextState) {
    return nextProps.id !== this.props.id;
}

Если shouldComponentUpdate возвращает false, то метод render() будет пропущен до следующего изменения параметров или состояния. По умолчанию (если не определен), всегда возвращает true. Может быть использован для улучшения бустродействия приложения (чтобы избежать лишних перерисовок), особенно если используется огромное количество компонентов.

componentWillUpdate

Вызывается перед вызовом метода render() при изменении параметров или состояния компонента.

componentWillUpdate: function(nextProps, nextState) {
    // в nextProps содержится объект с новыми параметрами
    // в nextState содержится объект с измененным состоянием
}

!!! Не используйте setState() в этом методе! Так у вас может произойти зацикливание!

componentDidUpdate

Вызывается сразу после вызова метода render() при изменении параметров или состояния компонента.

componentDidUpdate: function(prevProps, prevState) {
    // в prevProps содержится объект с предыдущими параметрами
    // в prevState содержится объект с состоянием до изменения
    // измененные параметры и состояние могут быть получены через this.props и this.state
}

Произведенные изменения уже отображены в DOM дереве. Обычно, в данном методе производят какие-то операции с DOM елементами согласно изменениям.

!!! Не используйте setState() в этом методе! Так у вас может произойти зацикливание!

componentWillUnmount

Вызывается перед тем, как компонент будет удален из DOM.

componentWillUnmount: function() {
    // обычно, в данном методе происходит некая уборка за компонентом
    // остановка таймеров, удаление ссылок на DOM елементы и т.д.
}

Весь жизненный цикл компонента можно представить в виде такой схемы

Весь жизненный цикл компонента

Дочерние компоненты

Иногда вместо того, чтобы писать так:

<Article author="Vasya Pupkin" text="Here is article itself" />

Очень хочется написать так:

<Article author="Vasya Pupkin"> Here is article itself </Article>

Для таких случаев существуют this.props.children. В компоненте Article можно просто обратиться к ним для получения всего содержимого между открывающимся и закрывающимся тегами.

var Acricle = React.createClass({
    render: function() {
        return (
            <div>
                <p>{this.props.children}</p>
                by {this.props.author}
            </div>
        );
    }
});

Inline стили

// для удобства работы со стилями они представлены в виде объекта,
// а не строки, объект со стилями передается в атрибут style
var divStyle = {
    color: 'white',
    height: 50, // можно не писать 'px', а использовать числа
    backgroundImage: 'url(' + imgUrl + ')', // вместо background-image
    WebkitTransition: 'all',// все префиксы с заглавной буквы
    msTransition: 'all' // кроме ms-*
};

ReactDOM.render(
    <div style={divStyle}>Hello World!</div>,
    mountNode
);

Refs (string attribute or callbacks)

Атрибут ref может быть callback функцией, которая будет немедленно исполнена, после того как компонент будет установлен. Указанный компонент будет передан в качестве параметра, и функция обратного вызова может сразу использовать компонент, или сохранить ссылки для дальнейшего использования. Стоит отметить что, при прикреплении ref на компонент DOM, такой как тег <div /> вы получите DOM узел обратно; в то время как при при присоединении ref к составному компоненту такому как <MyComponent />, вы получете экземпляр React класса. В последнем случае вы можете вызывать методы этого компонента, если таковые будут определены.

// для удобства работы с элементами DOM дерева в методе render(),
// мы используем refs(ссылка на элемент DOM),
// чтобы использовать свойства и методы полученного объекта 
var MyComponent = React.createClass({
    handleClick: function() {
        this.input.focus();
    },
    render: function() {
        return (
            <div>
                <input type="text" ref={ i =>  this.input = i  } />
                <button onClick={this.handleClick}>Focus</button>
            </div>
        );
    }
});

ReactDOM.render(
    <MyComponent />,
    document.getElementById('example')
);

React так же поддерживает использование строки (вместо обратного вызова):

   <input ref="myInput" />

Но стоит отметить тот факт что в документации разработчики утверждают что string refs считаются устаревшими. Рефы обратного вызова являются предпочтительными.

Как работают события в React

Если на странице есть 100 (или 1000) различных элементов, на которых вы назначили обработчики события onClick — React вместо того, чтобы назначать обработчик каждому, поставит только один обработчик на их общего предка, а там, уже с помощью всплытия, поймет на каком именно потомке произошло событие и обработает его. Такой подход упрощает инициализацию и экономит память.

События

Вопросы для самопроверки

  • В каком порядке и какие вызываются методы жизненного цикла при первом render'е компонента, при изменении параметров, при изменении состояния, при удалении компонента?
  • Вызовет ли дополнительный render использование setState() в методе componentWillReceiveProps?
  • Как влияет метод shouldComponentUpdate на render?
  • Какой из методов жизненного цикла следует использовать для снятия события с window?
  • Как обратиться к тому, что лежит между тегами <Component> Some more JSX here </Component> из компонента Component?
  • Зачем нужны refs и как к ним обращаться?
  • Чем отличается определение inline стилей для компонента в React от их использования в html? Как передать inline стили в компонент?
  • Зачем для событий используется bind? Когда его следует использовать?
  • Если вы на 1000 компонентов повесите 1000 событий, значит ли это, что будет в действительности объявлено 1000 событий? Почему?

Материалы

Установка node и npm

Установка и использование http-server

  • документация на npm
  • чтобы установить пишем: npm install http-server -g
  • для того, чтобы поднять сервер: http-server -p 8081

Cсылки:

Домашнее задание

Задание 1: Сделать выбор цвета для заметки

Уровень сложности: низкий

При создании новой заметки реализовать выбор ее цвета. Можно выбирать из всего спектра (<input type="color" />) или использовать только 5–7 ваших любимых цветов (как в Google Keep).

подсказка

Задание 2: Таймер

Уровень сложности: средний

Нужно усовершенствовать написанный таймер добавлением в него кнопок "Пауза", "Старт" и "Возобновить".

подсказка

Задание 3: Поиск по заметкам

Уровень сложности: средний

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

подсказка

Задание 4: To-do list

Уровень сложности: высокий

Написать список задач. Пользователь может добавить новую задачу, отметить ее как выполненную (просто вычеркнуть ее из списка) и фильтры "Все", "Завершенные" и "Новые". Задачи должны сохраняться в localStorage.

подсказка

Если есть вопросы пишите сюда