Как создать собственный React Hook – практическое руководство
Если вы работали с React, держу пари, что у вас была возможность использовать хуки. Но пробовали ли вы когда-нибудь создать свой собственный хук?
Сегодня я помогу вам создать свой первый собственный хук и объясню, как они могут улучшить вашу кодовую базу.
Зачем создавать собственные хуки?
Вы можете задаться вопросом: зачем мне вообще создавать новый хук React? В конце концов, в React есть все необходимые хуки, а все остальное кажется немного чрезмерным. Это правда, что в React есть множество мощных хуков, но знаете ли вы, что специальные хуки могут улучшить качество вашего кода?
Представьте, что у вас есть фрагмент кода React, который используется во многих компонентах. Как программист, вы не хотите повторяться и делаете повторяющийся код максимально пригодным для повторного использования. Вот почему хорошей идеей будет обернуть эти фрагменты в утилиты, компоненты или специальные перехватчики.
Создание собственных хуков не только упростит ваши компоненты, но и значительно уменьшит размер вашей кодовой базы. Помните, что меньше кода обычно означает лучшую читаемость и меньшую сложность кода.
Требования
Прежде чем прочитать это руководство, вам необходимо ознакомиться с React. Не поймите меня неправильно – вам не обязательно быть экспертом, но необходимо некоторое понимание основ.
Ваш первый индивидуальный хук - usePreviousProps
Мы создадим хук, отвечающий за отслеживание предыдущих значений свойств компонента. Это означает, что мы создадим собственный хук usePreviousProps
с нуля.
Один из наиболее распространенных случаев использования такого хука — когда вы имеете дело с анимацией. Например, представьте, что вам нужно выделить только что созданный элемент. Как можно определить, является ли он новым, не сравнивая текущие значения с предыдущими? Вот тут-то и вступает в игру наш новый хук.
Как создать собственный хук
Для начала нам нужно создать новый файл в каталоге hooks
вашего проекта — я решил назвать его use-previous-props.js
.
Имейте в виду, что хуки React редко используют синтаксис JSX (HTML), поэтому мы используем расширение .js
. Если вам нужно включить синтаксис JSX, необходимо изменить расширение на .jsx
. Но подумайте дважды, прежде чем делать это: если вам действительно нужен JSX, вам, вероятно, следует создать отдельный компонент вместо хука.
import { useEffect, useRef } from "react";
export default function usePreviousProps(value) {
const ref = useRef();
useEffect(() => {
ref.current = value;
});
return ref.current;
}
Как видите, наш хук очень похож на обычный функциональный компонент. Единственная разница заключается в return
операторе: он возвращает значение JavaScript вместо элемента HTML.
Хуки React часто возвращают значения, функции или и то, и другое. Например, хук useState
возвращает массив с двумя элементами: значением текущего состояния и функцией для обновления этого значения.
Теперь позвольте мне объяснить, как usePreviousProps
на самом деле работает:
const ref = useRef()
используется для сохранения ссылки при повторной визуализации компонента. В нашем случае мы будем использовать его для хранения предыдущего значения.- Хук
useEffect
будет обновлятьref.current
значение всякий раз, когда компонент перерисовывается. Это означает, что при измененииvalue
значениеref.current
будет обновлено, чтобы сохранить самое последнее значение свойства. Важно отметить, что все это происходит после завершения рендеринга компонента, поэтому во время повторного рендеринга он сохраняет предыдущее значение. return ref.current
возвращает значение из ссылкиref
.
Теперь наш специальный хук usePreviousProps
готов к использованию!
Как использовать собственный хук
Есть анимация, включающая в себя наш специальный хук usePrevoiusProps
.
Вот код, отвечающий за эту анимацию:
export default function Tile({ value }) {
const [scale, setScale] = useState(1);
const previousValue = usePreviousProps(value);
const hasChanged = previousValue !== value;
useEffect(() => {
if (hasChanged) {
setScale(1.1);
setTimeout(
() => setScale(1),
100 /* 100ms == 0.1s */
);
}
}, [hasChanged, setScale]);
const style = {
transform: `scale(${scale})`
};
return (
<div className="tile" style={style}>
{value}
</div>
);
};
Давайте сосредоточимся на этой строке: const previousValue = usePreviousProps(value)
.
Здесь previousValue
содержится предыдущее значение для этого компонента. Если это новый компонент, он возвращает undefined
.
В следующей строке константа hasChanged
помогает определить, следует ли выделить компонент. Если он новый и вернул undefined
раньше, он запускает анимацию выделения.
Несколькими строками позже я объявил хук useEffect
, который будет проверять, изменил ли компонент свое значение. Если это произошло, React выполнит анимацию выделения.
Резюме
Сегодня вы узнали, что хуки React очень похожи на функциональные компоненты. Единственное отличие — это их выходные данные, где они возвращают значения, массивы или функции JavaScript, а не элементы JSX.
В нашем руководстве вы узнаете, как создать собственный хук, который инкапсулирует функциональность переключения в вашем приложении React.
Как видите, создание собственных хуков — это не ракетостроение, и я надеюсь, что вдохновил вас на эксперименты и создание своих собственных.