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

Что такое HOC?

Поскольку в Javascript функции являются объектами первого класса и могут быть переданы в качестве аргументов функции или возвращены из функции, у нас есть шаблоны создания функций. Это делается путем создания функции более высокого порядка, которая либо принимает функцию в качестве аргумента, либо возвращает функцию.

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

с маршрутизатором

Одним из первых HOC, с которым я столкнулся, была функция withRouter из react-router. Его высокоуровневое описание может заключаться в том, что он предоставляет доступ к свойствам маршрутизатора (история, соответствие, местоположение) в компоненте, который передается в него. Но давайте посмотрим на код

Я пропустил часть кода выше, который обрабатывал импорт, и часть кода ниже, обрабатывающего возврат конечного компонента, но в остальном это весь withRouter HOC.

Итак, давайте разберем это:

  • withRouter написан как стрелочная функция, которая принимает компонент в качестве аргумента. Это компонент, который мы передаем ему, когда пишем withRouter(Component).
  • Затем у нас объявляется еще одна функция. Эта функция на самом деле является функциональным компонентом реакции без сохранения состояния.
  • Этот компонент удаляет все реквизиты, которые вы передали withRouter(Component), а затем возвращает ваш компонент с этими реквизитами, но теперь он заключен в компонент Router из react-router, что позволяет передавать эти реквизиты маршрутизатора.

И это все. Почему это полезно? Это полезно, потому что он явно передает свойства маршрутизатора и абстрагирует их за этой функцией withRouter, так что вам не нужно беспокоиться о том, есть ли они у компонента.

Создание собственного

Теперь, когда у нас есть представление о том, как работают эти HOC, давайте создадим тот, который мы могли бы использовать в проекте реагирования.

authenticationHOC: функция, которая принимает компонент, требующий аутентификации пользователя, и будет отображать этот компонент только в том случае, если в нашем хранилище избыточности есть значение isAuthenticated.

export default const authenticationHOC = Component => {
   class Authenticate extends Component {
      componentWillMount(){
         if(!this.props.isAuthenticated)
            //handle redirect/error message
      }
      componentWillUpdate(){
         if(!this.props.isAuthenticated)
            //handle redirect/error message
      }
      render(){
         return <Component {...this.props}/>
   }
   const mapStateToProps = ({currentUser}) => ({isAuthenticated})
   return connect(mapStateToProps)(Authenticate)
}

Здесь наш HOC принимает компонент в качестве аргумента и возвращает компонент, который подключен к нашему хранилищу реакций, со значением isAuthenticated из нашего состояния. Этот компонент, который просто отображает исходный компонент, если пользователь аутентифицирован, или обрабатывает некоторую логику, если пользователь не аутентифицирован.