shouldComponentUpdate, PureComponent, memo
Бывают ситуации, когда наша какая-то компонента обновляется многократно, хотя при этом приходящие в нее данные не изменились, а значит она возвращает тот же результат.
Вот пример, файл src/Profile/Profile.jsx
import React from 'react'; import s from './Profile.module.css'; import ProfileInfo from './ProfileInfo/ProfileInfo'; import MyPostsContainer from './MyPosts/MyPostsContainer'; const Profile = (props) => { return ( <div> <ProfileInfo profile={props.profile} status={props.status} updateStatus={props.updateStatus} /> <MyPostsContainer /> </div> ) } export default Profile;
Здесь мы отрисовываем компоненту Profile, которая обернута в контейнерную компоненту ProfileContainer (здесь это не показано) и обновляется при изменении аж 4 свойств, согласно mapStateToProps.
Но внутри Profile есть еще одна компонента – MyPostsContainer, что видно в 10 строке. В итоге она получается тоже перерисовывается каждий раз, когда перерисовывается и сама Profile, но каждый раз возвращает одно и то же, ведь в нее приходит все то же самое.
Нам нужно сообщить MyPostsContainer, чтобы она не перерисовывалась.
shouldComponentUpdate
В классовых компонентах для этого есть метод shouldComponentUpdate. Вот таким образом можно сказать нашей компоненте, чтобы она отрисовалась только один раз:
class MyPosts extends React.Component { shouldComponentUpdate(nextProps, nextState) { return false; } render() { .......
Конкретно в такмо виде shouldComponentUpdate не используется. Вместо возвращения false там должно быть какое-то сравнение приходящих с пропсов или стейта значений с новыми аналогичным значениями. Например:
shouldComponentUpdate(nextProps, nextState) { return NextProps.value != this.props.value || NextState.value != this.state.value; }
В настоящее время при такой записи перерисовки точно не будет, если определенные значения не изменились. Но, согласно документации, в будущем это будет только как рекомендация для Реакта. Также в докумендации говорится, что этот метод нужен только для повышения производительности. Но не стоит опираться на его возможность «предотвратить» рендер, это может привести к багам. Вместо этого используйте PureComponent.
PureComponent
Метод PureComponent делает по сути то же, что и shouldComponentUpdate, но он позволяет не не описывать поведение вручную, т.е. не указывать при изменении чего должен происходить рендеринг.
React.PureComponent применяется вместо базового React.Component, который обычно прописывается в классовых компонентах. Они очень похожи, разница только в том, что React.PureComponent не может реализовывать shouldComponentUpdate, а вместо этого сразу по умолчанию делает поверхносное сравнение пропсов и стейта.
Если компонента всегда рендерит одинаковый результат при одних и тех же пропсах и стейте, для повышения производительности можно использовать React.PureComponent. Для этого Component просто заменяется на PureComponent в месте импорта и в объявлении класса:
- было:
import React, {Component} from 'react'; ... class MyPosts extends React.Component { ....
- cтало:
import React, {PureComponent} from 'react'; ... class MyPosts extends React.PureComponent { ...
memo
Вот пример:
const MyPosts = React.memo(props => { ... return ( ... ) }); //вот здесь закрывающая скобка
Очень вероятно, что сейчас memo работает по умолчанию, как показывают отзывы и небольшие эксперименты.
Очень вероятно мемо не работает по умолчанию и некогда не будет работать по умолчанию, не вводите в заблуждение людей.
этой статье несколько лет, писал ее, когда я еще начинал изучать фронтенд. Это просто мои заметки, и верить здесь ничему однозначно нельзя)) На тот момент мне так казалось либо так говорилось в источнике (ролике на ютубе, где я брал материал).