Tailwind UI 드롭다운 메뉴 - React vs Svelte
실제로 드롭다운 메뉴를 만드는 것은 말처럼 간단하지 않습니다. 먼저 메뉴 외부에서 마우스 클릭을 처리하고 현재 열려 있는 메뉴를 닫아야 합니다. 둘째,
Escape
키를 눌러 지원하고 현재 메뉴가 열려 있으면 닫아야 합니다. 셋째, 메뉴에 멋진 애니메이션을 추가하여 더 생생하게 느껴져야 합니다.React에서 메뉴를 구현하는 것은 내가 기대했던 것만큼 간단하지 않았습니다. Tailwind 스타일 자체는 문제가 아니지만 "클릭 해제"또는 "외부 클릭"기능을 처리하고 Esc 키를 처리하는 방법을 파악하는 데 시간이 좀 걸렸습니다. 그 외에도 React에서 CSS 전환을 수행하는 방법을 연구해야 했습니다. Tailwind의 제작자는 React에 기능이 내장되어 있지 않기 때문에 유용한 코드transition library를 만든 것으로 나타났습니다.
"react click away listener"에 대해 Google search을 수행하는 것은 실제로 도움이 되지 않았습니다. NPM에서 "react click outside"및 "react click away"를 검색하면 필요한 것보다 훨씬 더 많은 결과가 반환되었습니다. 물론 많은 React 라이브러리가 있지만 이를 처리하는 훨씬 간단한 방법이 있어야 한다고 생각했습니다.
다음은 제가 만든 Next.js(React + TypeScript) 코드입니다.
import Link from 'next/link';
import React, { useState, useRef, useEffect } from 'react';
import { Transition } from '@tailwindui/react';
const Menu = ({ user }) => {
const [show, setShow] = useState(false);
const container = useRef(null);
useEffect(() => {
const handleOutsideClick = (event: MouseEvent) => {
if (!container.current.contains(event.target)) {
if (!show) return;
setShow(false);
}
};
window.addEventListener('click', handleOutsideClick);
return () => window.removeEventListener('click', handleOutsideClick);
}, [show, container]);
useEffect(() => {
const handleEscape = (event: KeyboardEvent) => {
if (!show) return;
if (event.key === 'Escape') {
setShow(false);
}
};
document.addEventListener('keyup', handleEscape);
return () => document.removeEventListener('keyup', handleEscape);
}, [show]);
return (
<div ref={container} className="relative">
<button
className="menu focus:outline-none focus:shadow-solid "
onClick={() => setShow(!show)}
>
<img
className="w-10 h-10 rounded-full"
src={user.picture}
alt={user.name}
/>
</button>
<Transition
show={show}
enter="transition ease-out duration-100 transform"
enterFrom="opacity-0 scale-95"
enterTo="opacity-100 scale-100"
leave="transition ease-in duration-75 transform"
leaveFrom="opacity-100 scale-100"
leaveTo="opacity-0 scale-95"
>
<div className="origin-top-right absolute right-0 w-48 py-2 mt-1 bg-gray-800 rounded shadow-md">
<Link href="/profile">
<a className="block px-4 py-2 hover:bg-green-500 hover:text-green-100">
Profile
</a>
</Link>
<Link href="/api/logout">
<a className="block px-4 py-2 hover:bg-green-500 hover:text-green-100">
Logout
</a>
</Link>
</div>
</Transition>
</div>
);
};
export default Menu;
React 구현을 마쳤을 때 Svelte에서 동일한 메뉴를 구현하는 방법에 대해 생각했습니다. 그래서 Svelte로 이식하는 데 약간의 시간이 걸렸습니다.
Svelte의 많은 장점 중 하나는 CSS 전환과 애니메이션이 내장되어 있다는 것입니다. 여기 제가 설명합니다.
<script>
import { onMount } from 'svelte';
import { scale } from 'svelte/transition';
export let user;
let show = false; // menu state
let menu = null; // menu wrapper DOM reference
onMount(() => {
const handleOutsideClick = (event) => {
if (show && !menu.contains(event.target)) {
show = false;
}
};
const handleEscape = (event) => {
if (show && event.key === 'Escape') {
show = false;
}
};
// add events when element is added to the DOM
document.addEventListener('click', handleOutsideClick, false);
document.addEventListener('keyup', handleEscape, false);
// remove events when element is removed from the DOM
return () => {
document.removeEventListener('click', handleOutsideClick, false);
document.removeEventListener('keyup', handleEscape, false);
};
});
</script>
<div class="relative" bind:this={menu}>
<div>
<button
on:click={() => (show = !show)}
class="menu focus:outline-none focus:shadow-solid"
>
<img class="w-10 h-10 rounded-full" src={user.picture} alt={user.name} />
</button>
{#if show}
<div
in:scale={{ duration: 100, start: 0.95 }}
out:scale={{ duration: 75, start: 0.95 }}
class="origin-top-right absolute right-0 w-48 py-2 mt-1 bg-gray-800
rounded shadow-md"
>
<a
href="/profile"
class="block px-4 py-2 hover:bg-green-500 hover:text-green-100"
>Profile</a>
<a
href="/api/logout"
class="block px-4 py-2 hover:bg-green-500 hover:text-green-100"
>Logout</a>
</div>
{/if}
</div>
</div>
물론 코드의 양은 React보다 Svelte에서 약간 적지만 인지 부하에 대해서는 어떻습니까? 어느 것이 더 읽기 쉽고 이해하기 쉬운가요? 당신이 판사입니다.
Reference
이 문제에 관하여(Tailwind UI 드롭다운 메뉴 - React vs Svelte), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/codechips/tailwind-ui-dropdown-menu-react-vs-svelte-3970텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)