React.js. Начало работы. Часть 10 из 12

27.10.2019

Теги: JavaScriptReact.jsWeb-разработкаКомпонентФреймворк

Оптимизация приложения

Быстрая работа с DOM — одно из самых больших преимуществ React. Но для оптимизации приложения, нужно позаботиться о том, чтобы не вызывать метод render() компонентов приложения без необходимости. Приложения, с которыми мы работали до этого момента, никогда явно не вызывали метод render(), это происходило автоматически.

Давайте уточним — метод вызывается автоматически в трех ситуациях:

  1. Обновляется свойство компонента
  2. Обновляется состояние компонента
  3. Вызывается метод render() родительского компонента

Все три ситуации могут могут привести к изменению визуального представления компонента. Наша задача — предотвратить вызов методов render(), когда в этом нет необходимости.

Рассмотрим еще раз выдвижное меню. И расставим вызов console.log() внутри всех методов render():

import React, {Component} from 'react';
import ShowButton from './ShowButton';
import SlideMenu from './SlideMenu';

class MenuContainer extends Component {
    /*.....*/
    render() {
        console.log('Метод render() компонента MenuContainer');
        return (
            <div>
                <ShowButton handleClick={this.toggleMenu} />
                <SlideMenu handleClick={this.toggleMenu} visibility={this.state.visible} />
            </div>
        );
    }
}

export default MenuContainer;
import React, {Component} from 'react';
import HideButton from './HideButton';
import './SlideMenu.css';

class SlideMenu extends Component {
    render() {
        console.log('Метод render() компонента SlideMenu');
        var visibility = 'hide';
        if (this.props.visibility) {
            visibility = 'show';
        }
        return (
            <div id="slide-menu" className={visibility}>
                <HideButton handleClick={this.props.handleClick} />
                <h3><a href="#">Первый элемент меню</a></h3>
                <h3><a href="#">Второй элемент меню</a></h3>
                <h3><a href="#">Третий элемент меню</a></h3>
                <h3><a href="#">Четвертый элемент меню</a></h3>
                <h3><a href="#">Пятый элемент меню</a></h3>
                <h3><a href="#">Шестой элемент меню</a></h3>
                <h3><a href="#">Седьмой элемент меню</a></h3>
            </div>
        );
    }
}

export default SlideMenu;
import React, {Component} from 'react';
import './ShowButton.css';

class ShowButton extends Component {
    render() {
        console.log('Метод render() компонента ShowButton');
        return (
            <button id="show-button" onClick={this.props.handleClick}><span>»</span></button>
        );
    }
}

export default ShowButton;
import React, {Component} from 'react';
import './HideButton.css';

class HideButton extends Component {
    render() {
        console.log('Метод render() компонента HideButton');
        return (
            <button id="hide-button" onClick={this.props.handleClick}><span>«</span></button>
        );
    }
}

export default HideButton;

Запустим приложение, откроем консоль разработчика, кликнем кнопку открытия меню, а потом кнопку закрытия:

MenuContainer.js:24 Метод render() компонента MenuContainer
ShowButton.js:6 Метод render() компонента ShowButton
SlideMenu.js:7 Метод render() компонента SlideMenu
HideButton.js:6 Метод render() компонента HideButton
MenuContainer.js:17 Изменение состояния меню
MenuContainer.js:24 Метод render() компонента MenuContainer
ShowButton.js:6 Метод render() компонента ShowButton
SlideMenu.js:7 Метод render() компонента SlideMenu
HideButton.js:6 Метод render() компонента HideButton
MenuContainer.js:17 Изменение состояния меню
MenuContainer.js:24 Метод render() компонента MenuContainer
ShowButton.js:6 Метод render() компонента ShowButton
SlideMenu.js:7 Метод render() компонента SlideMenu
HideButton.js:6 Метод render() компонента HideButton

Нетрудно заметить, что свойство handleClick, которое передается компоненту ShowButton не изменяется при каждом открытии и закрытии меню.Так что нужно предотвратить вызов метода render():

import React, {Component} from 'react';
import './ShowButton.css';

class ShowButton extends Component {
    shouldComponentUpdate(newProps, newState) {
        return false;
    }
    render() {
        console.log('Метод render() компонента ShowButton');
        return (
            <button id="show-button" onClick={this.props.handleClick}><span>»</span></button>
        );
    }
}

export default ShowButton;

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

MenuContainer.js:24 Метод render() компонента MenuContainer
ShowButton.js:9 Метод render() компонента ShowButton
SlideMenu.js:7 Метод render() компонента SlideMenu
HideButton.js:6 Метод render() компонента HideButton
MenuContainer.js:17 Изменение состояния меню
MenuContainer.js:24 Метод render() компонента MenuContainer
SlideMenu.js:7 Метод render() компонента SlideMenu
HideButton.js:6 Метод render() компонента HideButton
MenuContainer.js:17 Изменение состояния меню
MenuContainer.js:24 Метод render() компонента MenuContainer
SlideMenu.js:7 Метод render() компонента SlideMenu
HideButton.js:6 Метод render() компонента HideButton

Аналогично, нужно предотвратить вызов метода render() компонента HideButton:

import React, {Component} from 'react';
import './HideButton.css';

class HideButton extends Component {
    shouldComponentUpdate(newProps, newState) {
        return false;
    }
    render() {
        console.log('Метод render() компонента HideButton');
        return (
            <button id="hide-button" onClick={this.props.handleClick}><span>«</span></button>
        );
    }
}

export default HideButton;

Еще раз запустим приложение, откроем консоль разработчика, кликнем кнопку открытия меню, а потом кнопку закрытия:

MenuContainer.js:24 Метод render() компонента MenuContainer
ShowButton.js:9 Метод render() компонента ShowButton
SlideMenu.js:7 Метод render() компонента SlideMenu
HideButton.js:9 Метод render() компонента HideButton
MenuContainer.js:17 Изменение состояния меню
MenuContainer.js:24 Метод render() компонента MenuContainer
SlideMenu.js:7 Метод render() компонента SlideMenu
MenuContainer.js:17 Изменение состояния меню
MenuContainer.js:24 Метод render() компонента MenuContainer
SlideMenu.js:7 Метод render() компонента SlideMenu

Мы здесь поступили предельно просто, всегда возвращая false. Но лучше проверять значение свойства:

shouldComponentUpdate(newProps, newState) {
    if (newProps.handleClick === this.props.handleClick) {
        return false;
    } else {
        return true;
    }
}

Использование компонента PureComponent

Чтобы вручную не определять изменение свойства или состояния, можно использовать специальный компонент PureComponent:

import React, {PureComponent} from 'react';
import './ShowButton.css';

class ShowButton extends PureComponent {
    render() {
        console.log('Метод render() компонента ShowButton');
        return (
            <button id="show-button" onClick={this.props.handleClick}><span>»</span></button>
        );
    }
}

export default ShowButton;
import React, {PureComponent} from 'react';
import './HideButton.css';

class HideButton extends PureComponent {
    render() {
        console.log('Метод render() компонента HideButton');
        return (
            <button id="hide-button" onClick={this.props.handleClick}><span>«</span></button>
        );
    }
}

export default HideButton;
MenuContainer.js:24 Метод render() компонента MenuContainer
ShowButton.js:6 Метод render() компонента ShowButton
SlideMenu.js:7 Метод render() компонента SlideMenu
HideButton.js:6 Метод render() компонента HideButton
MenuContainer.js:17 Изменение состояния меню
MenuContainer.js:24 Метод render() компонента MenuContainer
SlideMenu.js:7 Метод render() компонента SlideMenu
MenuContainer.js:17 Изменение состояния меню
MenuContainer.js:24 Метод render() компонента MenuContainer
SlideMenu.js:7 Метод render() компонента SlideMenu

Поиск: JavaScript • React.js • Web-разработка • Компонент • Фреймворк • render • Оптимизация • PureComponent

Каталог оборудования
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Производители
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Функциональные группы
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.