Шаблон React HOC

В своем более раннем посте я говорил о составном паттерне. Составные шаблоны дают разработчикам гибкость в перегруппировке компонентов, и, следовательно, вы можете создавать разные дизайны.

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

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

Реализовать этот дизайн просто и использовать мощную концепцию замыканий.

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

Приведенное выше утверждение может сбивать с толку. Итак, давайте рассмотрим пример, чтобы понять это.

Допустим, мы создаем приложение для социальных сетей. Нам нужно создать виджет для отображения списка сотрудников.

В идеале можно было бы собрать такие компоненты:

const EmployeesList = ({employeesData}) => {
  return(
      <div>
         {filteredEmployeesList.map(employee =>
            <div key={employee.name}>
               <div>Employee Name: {employee.name}</div>
               <div>Department: {employee.department}</div>
            </div>
         )}
      </div>
  )
}

Давайте немного расширим этот пример и добавим некоторые дополнительные функции, такие как фильтрация всех сотрудников из определенного отдела.

const FilteredEmployeesList = ({ employeesData, someCriteria }) => {
   const filteredEmployeesList = employeesData.filter(employee => employee.someCriteria === someCriteria)
return (
      <div>
         {filteredEmployeesList.map(employee =>
            <div key={employee.name}>
               <div>Employee Name: {employee.name}</div>
               <div>Department: {employee.department}</div>
            </div>
         )}
      </div>
   )
}

Теперь, если я хочу повторно использовать этот компонент, чтобы продемонстрировать всем сотрудникам, я не могу. Это потому, что мы объединили логический и презентационный компоненты вместе.

HOC спешит на помощь.

Компонент HOC можно определить как:

const EnhancedComponent = higherOrderComponent(WrappedComponent);

WrappedComponent здесь будет EmployeesList компонентом, который мы создали ранее.

и higherOrderComponent можно определить как:

const withFilteredData = EmployeesList => ({ data, 
   someCriteria }) => {
     const transformedData = 
     data.filter(employee => employee.someCriteria === someCriteria)
     return <EmployeesList employeesData={transformedData} />
}

Собираем все это вместе:

const withFilteredData = EmployeesList => ({ data, 
   someCriteria }) => {
     const transformedData = 
     data.filter(employee => employee.someCriteria === someCriteria)
     return <EmployeesList employeesData={transformedData} />
}
const FilteredEmployeeComponent = withFilteredData(EmployeesList);
<FilteredEmployeeComponent someCriteria='department' data={employeeData} />

Теперь мы можем использовать withFilteredData там, где нужен фильтр, и EmployeesList везде.