【React】カスタムフックの作成と使い所と実例
Reactのカスタムフックの作成方法と使い方を紹介します。
Reactのカスタムフックとは
useStateなどのReact Hookを内部で使っている関数(フック)のことをカスタムフックといいます。
Reactのカスタムフックの使い所
ReactのHookなどを複数コンポーネントで使いまわしたいときにカスタムフックを使用します。
useStateなどのReactのHookは基本的にはコンポーネントのトップレベルでのみ使用可能です。
ただし、useのつく関数の中では、例外的に使用することができるというReactの決まりごとがあります。
React Hookを関数に切り出すことで、再利用できるようになります。
カスタムフックの関数名
カスタムフックの関数名は、必ずuseなんとかと、頭に「use」をつける必要があります。
カスタムフックの実例
import { createContext, useContext, useState } from "react";
const ModalContext = createContext();
export const ModalProvider = ({ children }) => {
const [showModal, setShowModal] = useState(false);
const showModalHandler = () => {
setShowModal(true);
};
const closeModalHandler = () => {
setShowModal(false);
};
return (
<ModalContext.Provider
value={{ showModal, showModalHandler, closeModalHandler }}
>
{children}
</ModalContext.Provider>
);
};
// カスタムフック
export const useModalContext = () => {
return useContext(ModalContext)
}
createContextとuseContextを使用しています。
これらの説明は、以下を参考にしてみてください。
カスタムフックは、useModalContext部分です。
useContextをリターンしています。その引数にModalContextというcreateContextで作成したコンテキストがあります。
これは、Providerで使いたいコンポーネントをラップして、childrenで使えるようにします。
そして、index.jsなどの使いたいコンポーネントで以下のようにしてラップします。
import * as ReactDOM from "react-dom/client";
import App from "./App";
import { ModalProvider } from "./context/modal-context";
import "./index.css";
const root = ReactDOM.createRoot(document.querySelector("#root"));
root.render(
<ModalProvider>
<App />
</ModalProvider>
);
すると、アプリ全体でvalueに設定した値
value={{ showModal, showModalHandler, closeModalHandler }}
にアクセスすることができます。
あとは、たとえばナビゲーションでモーダルを開きたいという場合、以下のように使います。
import { useModalContext } from "../../context/modal-context";
const Navbar = () => {
const { showModalHandler } = useModalContext();
return (
<nav>
<button id="theme__icon" onClick={showModalHandler}>
<IoColorPalette />
</button>
</nav>
);
};
export default Navbar;
そして、モーダルを閉じたいときは、モーダル部分で以下のように使います。
import { createPortal } from "react-dom";
import Card from "./Card";
import { useModalContext } from "../context/modal-context";
const ModalPortal = ({ children }) => {
const target = document.querySelector("#overlays");
return createPortal(children, target);
};
const Modal = ({ className, children }) => {
const { showModal, closeModalHandler } = useModalContext();
return (
showModal && (
<ModalPortal>
<section id="backdrop" onClick={closeModalHandler}></section>
<Card className={className}>{children}</Card>
</ModalPortal>
)
);
};
export default Modal;