Прежде всего, что такое редукс?

Redux - это реализация с открытым исходным кодом (не все ли?) Архитектуры flux, предложенной Facebook в качестве совместимого стандарта для работы с данными в больших приложениях React.

Созданный Дэном Абрамовым, который сейчас работает над create-react-app (кстати, лучшим генератором для создания готовых строительных лесов приложений React), он содержит все, что предлагается из шаблона потока в удобном для использования способ, а также содержит некоторые JS-уловки (например, определение пустой функции с последующей проверкой ее имени, чтобы определить, был ли минимизирован код), что не является основным содержанием этой статьи.

Сам Redux - очень простая реализация, и была интересная статья, в которой указывается, что шаблоны, используемые в реализации redux, могут быть реализованы всего за 12 строк кода. Это, конечно, без всех предложений по оптимизации и без проверок работоспособности, которые он обеспечивает для лучшего опыта разработчика.

Для использования redux в приложениях React в npm доступен модуль react-redux, который предоставляет очень простую connect функцию, которая (как вы уже догадались) соединяет ваш компонент с хранилищем redux.

Основное содержание этой статьи - как получить незначительную оптимизацию подключенных компонентов, которые используют свои собственные свойства для запроса состояния редукции.

Допустим, у нас есть приложение для ведения блога, и мы хотим, чтобы конкретный компонент MyBlogs отображал все блоги вошедшего в систему пользователя. У нас есть зарегистрированный пользователь где-то еще в нашем приложении, и мы передаем его компоненту MyBlogs в качестве опоры. Теперь мы хотим отобразить все блоги, автором которых является вошедший в систему пользователь. Redux mapStateToProps предлагает свойства компонента в качестве второго аргумента. Мы можем использовать их для запроса состояния редукции и возврата его части в зависимости от некоторой опоры компонента. Это будет выглядеть примерно так:

function mapStateToProps(state, ownProps) {
  return {
    blogs: state.blogs.filter(blog => blog.author === ownProps.user)
  };
}
export default connect(mapStateToProps)(MyBlogs);

Мы создаем реализацию mapStateToProps, которая использует user из собственных свойств компонента и возвращает все блоги из состояния redux для этого конкретного пользователя.

К счастью для нас, ребята, вносящие свой вклад в redux и react-redux, великолепны, открыты для новых идей и всегда вносят свой вклад в производительность библиотеки и документацию, поэтому они предлагают нам возможность выполнить здесь минимальную оптимизацию.

mapStateToProps теперь может возвращать функцию вместо объекта.

Примечание: в сложных сценариях, где вам нужно больше контроля над производительностью рендеринга, mapStateToProps() также может возвращать функцию. В этом случае эта функция будет использоваться как mapStateToProps() для конкретного экземпляра компонента. Это позволяет выполнять мемоизацию для каждого экземпляра. [из официальных документов]

Если redux получает реализацию, которая возвращает функцию, он выполняет закрытие для обертывания собственных свойств компонента и, следовательно, обходит вызов mapStateToProps каждый раз, когда компонент меняет свои свойства, полученные от родительского компонента. Он создает так называемый purePropsSelector. Как это делается, можно увидеть здесь.

Теперь мы можем переработать нашу реализацию компонента MyBlogs следующим образом и добиться небольшого повышения производительности.

function mapStateToPropsFactory(initialState, ownProps) {
  // a closure for ownProps is created
  // this factory is not invoked everytime the component
  // changes it's props
  return function mapStateToProps(state) {
    return {
      blogs:
        state.blogs.filter(blog => blog.author === ownProps.user)
    };
  };
}
export default connect(mapStateToPropsFactory)(MyBlogs);

TL;DR;

При использовании собственных свойств компонента внутри mapStateToProps оберните функцию mapStateToProps в mapStateToPropsFactory, который будет возвращать саму функцию вместо объекта напрямую, и redux не будет вызывать ваш mapStateToPropsFactory при каждом изменении родительского свойства.

Спасибо моему наставнику Оливеру Лазороски за то, что он указал мне на это, и я поделюсь его TL; DR; замечание по этому поводу:

Подумайте об этом так: если redux получает mapStateToProps, который имеет ownProps в качестве второго аргумента и возвращает объект, он отключает каждую оптимизацию, которую он делает для вашего подключенного компонента.

Это была моя первая из многих статей о среде, и я надеюсь, что она вам пригодится.