PureComponent и Components

Mostovoy Nikita
Feb 3, 2018 · 2 min read

#начинающим #react

Эта статья о реакт-компонентах, которые описаны как класс. Обратите внимание, вы также можете использовать функциональные реакт компоненты.

При разработке реакт-приложений обычно используют два типа компонентов:
1) React.Component
2) React.PureComponent

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

В react lyfecycle компонентов существуют два процесса: mounting и updating.

Mounting lifecycle выглядит так:

1) constructor
2) componentWillMount — deprecated
3) render
4) componentDidMount

Updating lifecycle:

1) componentWillReceiveProps
2) shouldComponentUpdate
3) componentWillUpdate — deprecated
4) render
5) componentDidUpdate

Разница между Component и PureComponent заключается в методе updating lifecycle: shouldComponentUpdate.

В Component этот метод выглядит так:

shouldComponentUpdate() {
return true;
}

В PureComponent:

shouldComponentUpdate(nextProps, nextState) {
return !shallowEqual(nextProps, this.props) || !shallowEqual(nextState, this.state);
}

PureComponent изначально определяет функцию, которая ответствена за принятие решения — нужно ли продолжать updating lifecycle или нет.

Разберем пример:

class A extends React.Component {
render() {
return (<B props={this.props.someProps}/>
}}class B extends React.PureComponent { render() {
return (/* some data */)
}
}

Вызывающий код

1: ReactDOM.render(<A someProps={1} />, root);2: ReactDOM.render(<A someProps={1} />, root);

1) Здесь, на второй строке, компонент A будет обновлен. Так как он не является чистым компонентом, и его shouldComponentUpdate вернет true;
2) PureComponent B получает задачу на ререндер, но его props не изменились;
3) shouldComponentUpdate класса B вернет false, так как ссылки на все поля props остались прежними. (т.е. this.props.someProps === nextProps.someProps);
4) Дальнейшие методы Updating lifecycle не вызываются.

Теперь попробуем обновить someProps:

1: ReactDOM.render(<A someProps={1} />, root);2: ReactDOM.render(<A someProps={2} />, root);

1) A ререндерится
2) PureComponent B получает задачу на ререндер, его someProps изменился
3) shouldComponentUpdate класса B вернет True (this.props.someProps !== nextProps.someProps);
4) Методы Updating lifecycle вызываются, компонент обновляется.

Если бы компонент B был объявлен не как PureComponent, а как обычный Component, то он бы обновился в обоих случаях.

Таким образом, PureComponent помогает нам сократить число операций и оптимизировать наш рендер “из коробки”.

Пара заметок:
1) Не нужно переопределять shouldComponentUpdate, если используете PureComponent.

2) Не нужно делать полное сравнение внутри shouldComponentUpdate следующим образом:

shouldComponentUpdate(nextProps, nextState) {
return !JSON.stringify(nextProps) === !JSON.stringify(this.props) || !JSON.stringify(nextState) === !JSON.stringify(this.state);
}

frontend-notes

Фронтенд-разработка, вопросы-ответы, советы и хаки.

frontend-notes

Фронтенд-разработка, вопросы-ответы, советы и хаки. Вопросы-предложения и прочее можно писать в телеграмм: @xnimorz.

Mostovoy Nikita

Written by

Lead developer at talantix.ru

frontend-notes

Фронтенд-разработка, вопросы-ответы, советы и хаки. Вопросы-предложения и прочее можно писать в телеграмм: @xnimorz.