Что такое хуки wordpress

Что такое хуки и зачем они нужны?

Генерация страницы в WordPress – это целый набор функций и запросов к базе данных. При этом сам “движок” и тема работают вместе для вывода контента. Браузер интерпретирует все эти данные и объединяет их в одну веб-страницу, которую в итоге увидит посетитель сайта.

Во всем коде WordPress разработчики включили так называемые “крючки”, чтобы разработчики могли “повесить” на них свой собственный код. Эти крючки и есть хуками.

Хуки в WordPress бывают двух видов:

экшены,фильтры.

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

Фильтры позволяют перехватывать и изменять данные по мере их обработки. Например, Вы можете захотеть вставить другой класс CSS в HTML-элемент WordPress или изменить некоторые блоки Ваших страниц.

Работу хуков можно рассмотреть на примере. Представьте себе, что система WordPress является большим предприятием, которое приглашает внешних подрядчиков для выполнения тех или иных задач. Такими подрядчиками являются хуки, которые не имеют постоянного места работы на предприятии. Они будут приглашены лишь в случае необходимости. Таким местами обитания подрядчиков (хуков) могут быть:

  • плагины;
  • файл functions.php внутри родительской или дочерней темы.

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

Каждый крючок помечен определенным именем (например, wp_head), что соответствует определенной части процесса предприятия WordPress (в случае wp_head – процесс создания раздела <head> в HTML-структуре конечной страницы). Получается, что крючки выезжают в вестибюль офиса предприятия, чтобы подрядчики могли ездить на них, и они делают это в определенном порядке. Например, хук wp_head выезжает и возвращается обратно до завершения <head>, а крюк wp_footer возвращается прямо перед завершением <body> и т.д. Таким образом, подрядчик всегда направляется на свой крючок, на определенную часть работы на предприятии.

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

Подытоживая все вышесказанное получается, что крючки – это то, что “приглашает” внешний код (от functions.php и плагинов и т.д.) в определенные области обработки PHP WordPress. Они могут делать что угодно: добавлять что-либо на страницу или делать совсем другие вещи, например, регистрировать ошибку или даже отправлять электронную почту.

Рассмотрим каждый из видов хуков более подробно.

Что такое «пользовательские хуки»

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

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

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

Завершающая реализация шаблона модуля

Мы можем решить эту загадку useState … поместив замыкание в другое замыкание! (Боже мой! Я слышал, ты любишь закрытие …)

Здесь мы решили использовать режим модуля для создания нашего мини-крючка React. Как и React, он может записывать состояние компонентов (в этом примере он может записывать только одно состояние для каждого компонента и записывать состояние в _val). Такой дизайн позволяет MyReact отображать ваши функциональные компоненты. Он может использовать соответствующее закрытие каждый раз, когда компонент обновляется, чтобы присвоить значения внутреннему _val.

Теперь это больше похоже на хуки в React.

ПРИМЕР

Поменяем местами название продукта и цену

В первой серии статей о том, как  изменить Woocommerce с помощью дочерей темы, мы установили плагин Simply Show Hooks

Обратите внимание на верхнюю панель сайта

Наведите курсор на название плагина и нажмите Show Action Hooks.

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

Так как мы будем менять местами вывод названия продукта и цены продукта, то нам нужен хук woocommerce_single_product_summary

Наведем на него курсор и видим все, что спрятано в этом хуке. Названия интуитивно понятны,

Мы видим, что woocommerce_template_single_price, который очевидно отвечает за отображение цены, имеет приоритет 10.

Все, что нужно сделать, это удалить его, а затем снова добавить, присвоив новый приоритет. Мы хотим поместить цену перед заголовком, за который отвечает woocommerce_template_single_title, у которого приоритет 5. Значит нужно сделать так, чтобы у woocommerce_template_single_price приоритет был меньше.

Открываем function.php и пишем следующие строки:

remove_action('woocommerce_single_product_summary', 'woocommerce_template_single_price'); // удалили цену

add_action('woocommerce_single_product_summary', 'woocommerce_template_single_price', 4); // поставили цену в начало перед названием продукта с приоритетом 4.

Посмотрим, что у нас вышло. Но предварительно отключим отображение хуков нажав на кнопку в правом верхнем углу.

Итак, результат

В следующей статье мы рассмотрим использование filter hook.

Резюме¶

Давайте построчно пробежимся по тому, что мы выучили и проверим наши знания:

  • Строка 1: Импортируем хук из React. Он позволяет функциональному компоненту хранить внутреннее состояние.
  • Строка 4: Объявляем внутри компонента новую переменную состояния, вызвав хук . Этот вызов возвращает пару значений, которым мы даём имена. Поскольку наша переменная состояния хранит количество сделанных по кнопке кликов, мы называем её . Чтобы проинициализировать её, мы передаём значение в качестве единственного аргумента функции . Второе возвращённое нам значение позволяет обновлять , поэтому мы называем её .
  • Строка 9: Когда пользователь кликает по кнопке, мы вызываем с приращённым значением. После этого React сделает повторный рендер, в котором использует уже новое значение .

Поначалу это всё может показаться слишком сложным. Не торопитесь! Если вы запутались в объяснении, ещё раз прочитайте приведённый код с начала до конца. Обещаем, если вы на минутку «забудете», как состояние работает в классах, и посмотрите на код свежим взглядом, всё станет ясно.

Совет: Что делают квадратные скобки?

Вы могли обратить внимание на квадратные скобки в месте, где объявляется переменная состояния:

Два имени в квадратных скобках не содержатся в API React. Названия переменным состояния выбираете вы:

Такой синтаксис в JavaScript называется
. Он означает, что мы создаём две новые переменные, и . Во будет записано первое значение, вернувшееся из , а в — второе, что равносильно такому коду:

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

Совет: Использование нескольких переменных состояния

Объявлять переменные состояния через пару удобно ещё и тем, что когда нам нужны несколько переменных, мы можем назвать каждую из них собственным именем:

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

Использовать несколько переменных состояния совсем не обязательно, потому что они могут быть объектами или массивами, которые группируют связанные по смыслу данные

Обратите внимание, что, в отличие от в классах, обновление переменной состояния всегда замещает её значение, а не осуществляет слияние

Подробные рекомендации о разделении независимых переменных состояния вы найдёте .

Как создать хуки?

Пусть в компоненте, принадлежащем чату (приложению), отображается уведомление о нахождении пользователя «В сети»:

import React, { useState, useEffect } from 'react';

function FriendStatus(props) {

 const  = useState(null);
 useEffect(() => {
   function handleStatusChange(status) {
     setIsOnline(status.isOnline);
   }
   ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
   return () => {
     ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
   };
 });

  if (isOnline === null) {
    return 'Загрузка...';
  }
  return isOnline ? 'В сети' : 'Не в сети';
}

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

Чтобы решить эту задачу, в компонент можно скопировать логику, которая приведена выше:

import React, { useState, useEffect } from 'react';

function FriendListItem(props) {
  const  = useState(null);  useEffect(() => {    function handleStatusChange(status) {      setIsOnline(status.isOnline);    }    ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);    return () => {      ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);    };  });
  return (
    <li style={{ color: isOnline ? 'green' : 'black' }}>
      {props.friend.name}
    </li>
  );
}

Конечно, этот способ совсем не простой и короткий.

Поделимся логикой с и . В React существует два способа разделения логики:

  • render props;
  • компоненты высшего порядка.

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

Разделить логику между двумя функциями JavaScript можно, если извлечь ее в еще одну, третью функцию.

Первый пользовательский хук — :

import { useState, useEffect } from 'react';

function useFriendStatus(friendID) {  const  = useState(null);

  useEffect(() => {
    function handleStatusChange(status) {
      setIsOnline(status.isOnline);
    }

    ChatAPI.subscribeToFriendStatus(friendID, handleStatusChange);
    return () => {
      ChatAPI.unsubscribeFromFriendStatus(friendID, handleStatusChange);
    };
  });

  return isOnline;
}

Этот хук подписывает нас на статус пользователя. является здесь аргументом:

function useFriendStatus(friendID) {
  const  = useState(null);

  // ...

  return isOnline;
}

Наша изначальная цель — удалить повторяющуюся логику из и .

Когда логика извлечена из , можно ее использовать:

function FriendStatus(props) {
  const isOnline = useFriendStatus(props.friend.id);
  if (isOnline === null) {
    return 'Loading...';
  }
  return isOnline ? 'Online' : 'Offline';
}
function FriendListItem(props) {
  const isOnline = useFriendStatus(props.friend.id);
  return (
    <li style={{ color: isOnline ? 'green' : 'black' }}>
      {props.friend.name}
    </li>
  );
}

Что здесь произошло? Мы извлекли код из двух функций и поместили в отдельную функцию.

Важно! Используйте в начале каждого хука. Это нужно для автоматической проверки правил хуков

Хуки, используемые в двух компонентах, не имеют одинакового состояния. Каждый вызов хука изолирован.

Как мы уже говорили, хуки — это те же функции. А потому можно передавать информацию между ними.

Давайте рассмотрим пример использования компонента, демонстрирующего, находится ли пользователь сейчас онлайн:

const friendList = ;

function ChatRecipientPicker() {

 const  = useState(1);
 const isRecipientOnline = useFriendStatus(recipientID);

  return (
    <>

     <Circle color={isRecipientOnline ? 'green' : 'red'} />
     <select
        value={recipientID}
        onChange={e => setRecipientID(Number(e.target.value))}
      >
        {friendList.map(friend => (
          <option key={friend.id} value={friend.id}>
            {friend.name}
          </option>
        ))}
      </select>
    </>
  );
}

Идентификатор пользователя сохраняется в и обновляется в случае выбора в другого пользователя.

Хук возвращает значение , а значит его можно передать в в качестве аргумента:

const  = useState(1);
  const isRecipientOnline = useFriendStatus(recipientID);

Так можно узнать, находится ли пользователь в сети.

Пользовательские хуки гибкие, их можно использовать в связке друг с другом.

Как работают хуки в WordPress?

У некоторых функций WordPress есть хуки то есть события. Например если взять основные функции WordPress, такие как: wp_head.php, wp_content.php, wp_footer.php. У этих функций есть так называемые ( хук — событие ).

С помощью хуков мы можем как бы цепляться за определенные события происходящие во время загрузки сайта. Цеплять можно собственные функции совершать как бы (перехват). Таким образом добавлять или удалять какие то элементы дизайна сайта, делать проверку и возвращать данные обратно, добавлять дополнительный функционал сайту и многое другое.

Фильтры и события в WordPress

Что такое фильтры и события, скажете вы? На первый взгляд кажется, что для понимания, это сложно но это не так. И мы в этом сегодня разберемся.

Функции add_filter() и add_action() — как раз и работают с хук — событиями. Работают функции совершенно одинаково. Разница заключается только в логике работы. Фильтры перехватывают события выполняют какие либо действия и возвращают его назад. События же работают также только ни чего не возвращают.

Параметры функции add_filters()

Здесь мы рассмотрим функцию add_filters() и разберем какие параметры она использует.

add_filters($hook_name, $function, $priority, $args_num); — прикрепляет пользовательскую функцию к хуку — фильтру и использует четыре параметра — $hook_name, $function, $priority и $args_num.

$hook_name(строка) (обязательный) Имя хука — события, для которого срабатывает функция в параметре $function_to_add.

$function(строка) (обязательный) Имя функции, которая срабатывает для указанного в параметре хука — события. Имя функции указывается в виде строки взятое в кавычках: ‘название_функции’. Для функций внутри классов указывается массив: array(‘название_класса’, ‘название_функции’).

$priority(число) Приоритет функций для одного и тоже хука — события. Чем больше число, тем позднее будет выполнятся функция. Функции с одинаковым приоритетом, выполняются в порядке их добавления к массиву фильтров.

$args_num(число) Количество аргументов передаваемых фильтром функции. Некоторые фильтры могут передавать больше чем 1 аргумент.

Параметры функции apply_filter()

Так же разберем функцию apply_filter() и её параметры.

apply_filter($hook_name, $value, $args); — выполняет пользовательскую функцию через хук — фильтр и использует четыре параметра — $hook_name, $value, $args.

$hook_name(строка) (обязательный) Имя хук — фильтра.

$value(строка/массив/число/объект/логический) (обязательный) Значение, которое передается функции в первом её аргументе. Другими словами — значение, которое необходимо отфильтровать.

$args(строка/массив/число/объект/логический) Дополнительные значения, которые будут передаваться функции.

Пример работы фильтров

Рассмотрим пример работы фильтров по небольшим кусочкам кода для более легкого понимания.

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

Параметры функции add_action()

add_action($hook_name, $function, $priority, $args_num); — прикрепляет пользовательскую функцию к хуку — событию и использует четыре параметра — $hook_name, $function, $priority и $args_num.

$hook_mame(строка) (обязательный) — Имя хука — действия, к которому будет цепляться функция.

$function(строка/замыкание) (обязательный) — Имя функции, которая должна быть вызвана во время срабатывания события.

$priority(число) — Приоритетное выполнение функции. На хук может быть прицеплено до нескольких функций. Приоритетность функций решает последовательность их выполнения. Чем меньше число тем раньше выполняется функция.

$args_num(число) — Количество аргументов, которые принимает функция.

Параметры функции do_action()

do_action($hook_name,$args); — выполняет пользовательскую функцию через хук — событие.

Использует два параметра — $hook_name и $args.

$hook_name(строка) (обязательный) Имя созданного хука.

$args(строка/массив/число/объект/логический) Аргумент, который будет передан функции. Функции можно передавать бесконечное количество аргументов…

Пример работы событий

Рассмотрим некоторый пример работы события для общего понимания работы хуков.

Предложенный вам пример наглядно показывает работу хук — события. Здесь вы можете видеть функцию которая выводит надпись — «Привет Мир!», привязку этой функцию к созданному хуку — событию и ее выполнение.

Таким образом вы сами сможете использовать свои функции прикреплять к определенным событиям и выводить различные данные.

Как удалить созданные хуки — фильтры и хуки — события

Для удаления хуков фильтров и событий нужно использовать две основные функции remove_filter() и remove_action(). Они работают абсолютно одинаково и разница у них заключается лишь в логике применения также как у фильтров и событий.

Параметры функций удаления хука — события и хука — фильтра

Как было сказано ранее, функции — работают абсолютно одинаково поэтому и параметры у функций совершенно одинаковые. Ниже вы можете видеть параметры двух функций — remove_filter() и remove_action().

Здесь показаны функции с указанием размещения параметров и описание самих параметров.

$hook_name(строка) (обязательный) Имя фильтра, функцию которого нужно будет удалить.

$function_name(строка) (обязательный) Имя функции, которая должна быть удалена.

$priority(число) Приоритет хука (функции), который был установлен во время добавления.По умолчанию: 10

$args(удален)

Примеры удаления хука — события

К примеру вы выводите некоторую надпись удалив при этом из текста html — теги где то на сайте и захотели её удалить, то при этом нужно сделать как показано на скриншоте.

Так как при привязке функции к хуку создается массив хуков — событий. Из этого массива вы и удаляете хук — событие с помощью функции remove_action() также как и remove_filter().

Итак мы с вами разобрались, что такое хуки, рассмотрели работу с фильтрами и событиями, научились удалять хуки — события и хуки — фильтры. Надеюсь предложенный материал будет вам полезен.

Number of arguments

Usually hooks provide some additional data which are relevant and useful for the callback functions. For example the action (runs whenever a post gets updated) provides two possible arguments; the post ID and the post object. These are useful for operations you commonly need to run at this hook (for example if you want to save a post meta, you need the post ID).

If no number of arguments was provided for an action or filter, it defaults to 1. This is why you don’t need to define 1 on to access the variable the filter is hooked onto. Actions, however, can pass no arguments even though the number of arguments is set to 1 as default.

Let’s look at an example of defining number of arguments and how we access them in our callback function:

add_action('save_post', 'my_function_name', 10, 2);
function my_function_name($post_id, $post) {
	// Do your stuff
}

In the above example, we tell WordPress to pass two arguments to our callback function. Remember that we need to define priority as third parameter so usually we define the default, which is 10. As for our callback function we can now define the same number arguments we asked for, in the example above was 2.

If we had in the above example set number of arguments to 1, only the first argument in our callback function would be populated. The second, , would be undefined.

apply_filters()

Применяет прикрепленную к указанному фильтру PHP функцию. Прикрепляется функция с помощью add_filter().
Используется там, где нужно изменить значение переменной (например текст).
Используется в плагинах и темах, для создания хуков-фильтров (зацепок пользовательских функций).
Новые фильтры должны иметь уникальные названия и не должны совпадать с уже имеющимися в WP названиями фильтров.

Возвращает

Отфильтрованное значение $value, которое передается функции-обработчику хука.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

<?php

apply_filters( $tag, $value, $var … );

$tag(строка) (обязательный)

Названиефильтра.

Поумолчанию нет

$value(строкамассивчислообъектлогический) (обязательный)

Значение, которое будет передаваться функции в её первом аргументе, другимисловами — значение, которое нужно отфильтровать.

Поумолчанию нет

$var(строкамассивчислообъектлогический)

Дополнительныезначения, которые будет передавать фильтр функции.

Поумолчанию нет

?>

1
2
3
4
5
6
7

<?php

$myvar = apply_filters( $tag, $value );

$myvar = apply_filters( $tag, $value, $var1, $var2, … );

add_filter()

?>

Прикрепляет указанную PHP функцию к указанному хукe-фильтру. Так, во время срабатывания фильтра значение будет обработано указанной PHP функцией.

Фильтры это, своего рода, зацепки внутри кода, через которые можно «отфильтровать» какие-либо данные. Например, в период получения и вывода текста на экран из базы данных, можно «на лету» изменить (отфильтровать) этот текст и вывести на экран уже измененный вариант текста. И благодаря фильтру для этого нам не придется редактировать функцию вывода в файлах движка, а можно подключиться к функции вывода через файл шаблона, использовав заранее предусмотренный разработчиками фильтр.

add_filter() не делает никаких проверок: существует ли прикрепляемая функция или передается ли название функции в виде строки и т.д.. Сделано это, чтобы add_filter() работала максимально быстро.

Базовый список фильтров смотрите на: https://codex.wordpress.org/Plugin_API/Filter_Reference

true или false, в зависимости от того удалось или нет добавить новый фильтр.

1
2
3

<?php

add_filter( $tag, $function_to_add, $priority, $accepted_args );

?>

$tag(строка) (обязательный)
Название фильтра, для которого будет срабатывать функция определенная в параметре $function_to_add.
По умолчанию: нет$function_to_add(строка) (обязательный)
Название функции, которая будет срабатывать для указанного в предыдущем параметре фильтра. Название функции нужно указывать в виде строки: ‘название_функции’. Для функций внутри классов указываем массив: array(‘название_класса’, ‘название_функции’)
По умолчанию: нет$priority(число)
Приоритет выполнения функций для одного и того же фильтра. Чем больше число, тем позднее будет выполнятся функция: например, сначала 10 потом 20. Функции с одинаковым приоритетом, будут выполнятся в порядке их добавления к массиву фильтров.
По умолчанию: 10$accepted_args(число)
Количество аргументов передаваемых фильтром функции. Некоторые фильтры могут передавать больше чем 1 аргумент, допустим — 2, для таких случаев нужно указывать 2 в этом параметре.
По умолчанию: 1

Actions в WooCommerce

Есть 2 различных типа хуков, которые вы можете использовать для дальнейшей настройки вашего магазина WooCommerce. Также вы можете использовать плагин WooCustomizer, который позволяет редактировать множество фильтров без необходимости знать, как кодировать.

Actions (action hook)

Actions размещаются по всему WooCommerce с помощью функции do_action (‘action_name’), и поэтому вы можете использовать имя действия, чтобы указать, где вы хотите выполнить добавляемый код.

Чтобы добавить свой пользовательский код, вы просто создаете новую функцию php с вашим кодом внутри и указываете, где вы хотите запустить код, добавляя имя действия в качестве первого параметра в функции add_action ().

Пример:

add_action( 'action_name', 'your_custom_function_name', Priority );

function your_custom_function_name() {

// Your code

}

Таким образом, вы просто говорите коду WooCommerce: “добавьте мое действие, когда do_action запускается”.

Чтобы удалить action нужно применить команду remove_action(‘action_name’, ‘function_name’, Priority).

Creating your own hooks

You can define your own actions and filters. If you are a theme or plugin developer, you are encouraged to do so, as to allow others to modify your code without changing the source code.

Register an action with , and register a filter with .

The requires a minimum of 1 parameter; the hook name. Keep in mind that the hook name must be unique (don’t call it e.g. as this is a core WordPress hook). Place the wherever you want the hook to appear. For example you can place the hook in your theme’s , right after body as to define a hook where developers can output scripts or other content.

...
<body>
	<?php do_action('mytheme_after_body'); ?>

You can add as many parameters to as you want after the hook name. Try to keep in mind what data developers would need in your hooks, that are not easily accessible otherwise.

The requires a minimum of 2 parameters; the hook name, and the variable which you are registering the filter on. For example, your theme can register a filter around some HTML classes to allow developers to modify or add to these:

<section class="<?php echo apply_filters('mytheme_section_classes', 'section default-class'); ?>">
	...
</section>

As with actions, you can add as many parameters to as you want after the two mandatory parameters.

Хуки – это Действия (Actions) и Фильтры (Filters)

В двух словах, действия запускают какой-нибудь код, а фильтры – изменяют переменные. Давайте рассмотрим пару примеров:

add_action( 'save_post', 'notify_administrator', 10, 3 );

function notify_administrator( $post_id, WP_Post $post, $update ) {
	// Really important code here ... 

	wp_mail( $admin_email, $subject, $message );
}

add_filter( 'post_class', 'modify_post_classes', 10, 3 );

function modify_post_classes( $classes, $class, $post_id ) {
	if ( in_array( get_post_type( $post_id ),  ) ) {
		$classes[] = 'dark-theme';
	}

	return $classes;
}

Обратите внимание, что колбэк для фильтра () обязательно должен вернуть данные, немного измененные или похожие на те, которые он принимает первым аргументом ()

Экшены

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

function wpschool_action_example() {
    echo "Текст в шапке сайта.";
}
add_action( 'wp_head', 'wpschool_action_example' );

Функция wpschool_action_example() означает, что это экшен (или действие) и не содержит никаких аргументов. В функции присутствует один единственный оператор – echo “Текст в шапке сайта.” Это то, что делает функция. echo – это команда PHP, которая выводит что-либо на экран.

В строке add_action( ‘wp_head’, ‘wpschool_action_example’ ) содержится служебная команда add_action(), которая “подвешивает” функцию wpschool_action_example() на крючок экшена wp_head. В итоге текст “Текст в шапке сайта.” будет напечатан в самом начале пашки (или хедера), там, где автор темы разместил крючок действия wp_head.

На реальном сайте это будет выглядеть следующим образом:

Также этот пример можно переделать для футера сайта,изменив лишь название крючка:

function wpschool_action_example() {
    echo "Текст в хедере сайта.";
}
add_action( 'wp_footer', 'wpschool_action_example' );

в заключении

На этом этапе мы очень далеко расширили исходный пример. Вы можете попробовать использовать одну строку кода для реализации useRef, или позволить функции рендеринга принять JSX и смонтировать его в DOM, или реализовать бесчисленное множество других важных деталей, которые мы проигнорировали в версии с 28-строчной обработкой. Надеюсь, что теперь вы приобрели некоторый опыт использования замыканий в контексте и в вашем уме есть полезная модель, которая может объяснить, как работают React Hooks.

Я хотел бы поблагодарить Дэна Абрамова и Дивью Сасидхарана за рецензирование черновика этой статьи. Основываясь на их ценных отзывах, я улучшил эту статью. Все остальные ошибки — мои.

Хук usePageBottom

В приложениях React в некоторых случаях важно знать, когда пользователь прокрутил страницу до конца. Так например в Instagram реализована «бесконечная «прокрутка, то есть если пользователь попадает в нижнюю часть страницы, то подгружаются и отображаются новые сообщения

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

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

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

// utils/usePageBottom.js
import React from "react";

export default function usePageBottom() {}

И так, нам необходимо определить момент, когда пользователь попадет в нижнюю часть страницы. Мы можем определить его произведя несложные расчеты, используя информацию, полученную из свойств глобального объекта . Отметим, что перед тем как обращаться к нему, нам нужно убедиться, что компонент, в котором вызывается хук, смонтирован. Для этого мы будем использовать хук , в который передадим пустой массив зависимостей.

// utils/usePageBottom.js
import React from "react";

export default function usePageBottom() {
  React.useEffect(() => {}, []);
}

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

// utils/usePageBottom.js
import React from "react";

export default function usePageBottom() {
  React.useEffect(() => {
    window.innerHeight + document.documentElement.scrollTop === document.documentElement.offsetHeight;
  }, []);
}

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

// utils/usePageBottom.js
import React from "react";

export default function usePageBottom() {
  const  = React.useState(false);

  React.useEffect(() => {
    const isBottom =
      window.innerHeight + document.documentElement.scrollTop ===
      document.documentElement.offsetHeight;
    setBottom(isButton);
  }, []);

  return bottom;
}

Вот так будет в результате выглядеть наш код. Однако в таком виде он работать не будет. Давайте разберемся почему так происходит.

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

// utils/usePageBottom.js
import React from "react";

export default function usePageBottom() {
  const  = React.useState(false);

  React.useEffect(() => {
    function handleScroll() {
      const isBottom =
        window.innerHeight + document.documentElement.scrollTop 
        === document.documentElement.offsetHeight;
      setBottom(isButton);
    }
    window.addEventListener("scroll", handleScroll);
  }, []);

  return bottom;
}

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

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

// utils/usePageBottom.js
import React from "react";

export default function usePageBottom() {
  const  = React.useState(false);

  React.useEffect(() => {
    function handleScroll() {
      const isBottom =
        window.innerHeight + document.documentElement.scrollTop 
        === document.documentElement.offsetHeight;
      setBottom(isButton);
    }
    window.addEventListener("scroll", handleScroll);
    return () => {
      window.removeEventListener("scroll", handleScroll);
    };
  }, []);

  return bottom;
}

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

The Hooks naming Convention

The WordPress documentation doesn’t have recommendations about hooks naming, but it’s significant for WordPress products. I slightly prefer that a linter also checked the hooks’ names as with all coding standards. It doesn’t matter how your team will check hooks’ names, but I’m sure that you should do it.

For example, you can use Fully Qualified Class Name (FQCN) + method name + extra detail(optional). Let’s update our API class due to the hooks’ names convention:

As a result, we always know how to name a hook and won’t have any conflicts with other codebase parts. Sometimes the names have incorrect word-order or non-obviously names, but we have a clear logic for all hooks in your project, which you can automatize.

The WordPress documentation has one more interesting piece of information about naming dynamic hooks. Use curly brackets:

instead of:

The reason is simplifying work for code analysis tools, such as quick search in PhpStorm, hooks generator for documentation. etc.

That’s all. Happy hooking!

Рейтинг
( Пока оценок нет )
Editor
Editor/ автор статьи

Давно интересуюсь темой. Мне нравится писать о том, в чём разбираюсь.

Понравилась статья? Поделиться с друзьями:
Люкс-хост
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: