Как только вы освоите основы 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 из нашего состояния. Этот компонент, который просто отображает исходный компонент, если пользователь аутентифицирован, или обрабатывает некоторую логику, если пользователь не аутентифицирован.