😊
【NextJs14】NextJs14 と 便利なライブラリ【#13Usehooks-ts 】
【#13Usehooks-ts 】
YouTube: https://youtu.be/AjAAdnDfL4A
今回はusehooks-tsの便利な機能を見ていきます。
まずは、「isMounted」の部分を「useIsClient」を使って
書き換えていきます。
components/providers/modals-provider.tsx
"use client";
import { useEffect, useState } from "react";
import { useUser } from "@clerk/nextjs";
import { useIsClient } from "usehooks-ts";
import { UserProfileModal } from "../modals/user-profile-modal";
export const ModalsProvider = () => {
const [isMounted, setIsMounted] = useState(false);
const isClient = useIsClient();
const { user } = useUser();
// useEffect(() => {
// setIsMounted(true);
// }, []);
// if (!isMounted) {
// return null;
// }
if (!isClient) {
return null;
}
return (
<>
<UserProfileModal email={user?.emailAddresses[0].emailAddress || ""} />
</>
);
};
次に「useEventListener」を使って
キーボード入力でモーダルが開くようにします。
app/(main)/_components/main-sidebar.tsx
"use client";
import { Copy, Database, Home, Image, ShieldCheck, User } from "lucide-react";
import { Separator } from "@/components/ui/separator";
import { MainSidebarItem } from "./main-sidebar-item";
import { Button } from "@/components/ui/button";
import { useModal } from "@/store/use-modal-store";
import { useEffect } from "react";
import { useEventListener } from "usehooks-ts";
export type MenuItem = {
id: string;
href: string;
pathname: string;
label: string;
icon: React.ReactNode;
};
const menuItems = [
{
id: "0",
href: "/home",
pathname: "/home",
label: "Home",
icon: <Home className="h-5 w-5 mr-3 group-hover:text-white" />,
},
{
id: "1",
href: "/account",
pathname: "/account",
label: "Account",
icon: <User className="h-5 w-5 mr-3 group-hover:text-white" />,
},
{
id: "2",
href: "/images",
pathname: "/images",
label: "Images",
icon: <Image className="h-5 w-5 mr-3 group-hover:text-white" />,
},
{
id: "3",
href: "/data",
pathname: "/data",
label: "Data",
icon: <Database className="h-5 w-5 mr-3 group-hover:text-white" />,
},
{
id: "4",
href: "/protected",
pathname: "/protected",
label: "Protected",
icon: <ShieldCheck className="h-5 w-5 mr-3 group-hover:text-white" />,
},
];
export const MainSidebar = () => {
const { onOpen } = useModal();
const modalOpen = (e: KeyboardEvent) => {
if (e.key === "c" && (e.metaKey || e.ctrlKey)) {
e.preventDefault();
onOpen();
}
};
// useEffect(() => {
// window.addEventListener("keydown", modalOpen);
// return () => {
// window.removeEventListener("keydown", modalOpen);
// };
// }, []);
useEventListener("keydown", modalOpen);
return (
<div className="w-full flex py-4 px-4 flex-col items-center">
<div className="w-full">
<h3 className="text-lg">Menu</h3>
</div>
<Separator className="bg-slate-400 mt-2" />
<div className="w-full py-4">
<ul>
{menuItems.map((item) => (
<MainSidebarItem key={item.id} item={item} />
))}
</ul>
</div>
<Separator className="bg-slate-400 mt-2" />
<div className="w-full py-4">
<Button
onClick={onOpen}
className="w-full flex items-center gap-x-2"
variant="primary"
>
<Copy className="h-4 w-4" />
Copy Email
</Button>
</div>
</div>
);
};
Discussion