Hướng dẫn tạo modal trong Next.js 14
Bài viết này sẽ hướng dẫn bạn từng bước để tạo một modal trong Next.js 14, kết hợp với Context API để quản lý trạng thái modal một cách hiệu quả.
1. Tạo Context API cho modal
Đầu tiên, chúng ta cần khởi tạo Context API để xử lý và quản lý logic cho modal. Đoạn mã dưới đây sẽ hướng dẫn bạn cách thực hiện điều này:
javascript
"use client";
import { $ModalKeys } from "@/collects/modals";
import { Dispatch, PropsWithChildren, SetStateAction, createContext, useState } from "react";
type $ToggleFn = { key: $ModalKeys; data?: any };
type $Show = { [T in $ModalKeys]: { open: boolean; data?: any; } };
type $_Modal = { onToggle: (props: $ToggleFn) => void; show: $Show; setShow: Dispatch<SetStateAction<$Show>>; };
export let _$modal = {} as $_Modal;
const useLogic = () => {
const [show, setShow] = useState({} as $Show);
const onToggle = (props: $ToggleFn) => {
const { key, data } = props;
setShow((prev) => ({
...prev,
[key]: { ...prev[key], open: !prev[key]?.open, data },
}));
};
_$modal = { onToggle, show, setShow };
return { onToggle, show, setShow };
};
type ValueCtx = ReturnType<typeof useLogic>;
export const ModalCtx = createContext({} as ValueCtx);
export const ModalProvider = ({ children }: PropsWithChildren) => {
const valueCtx = useLogic();
return <ModalCtx.Provider value={{ ...valueCtx }}>{children}</ModalCtx.Provider>;
};
2. Tạo Component Modal
Tiếp theo, chúng ta sẽ tạo một component modal. Đoạn mã dưới đây sẽ giúp bạn thực hiện điều này:
javascript
"use client";
import cx from "classnames";
import React, { useContext } from "react";
import ReactDOM from "react-dom";
import styles from "./styles.module.scss";
import { ModalCtx } from "./context";
type $Modal = { open?: boolean; onToggle: () => void; data?: any; };
type $Props = { set?: { open?: $Modal["open"]; isCloseOutside?: boolean; clsOverlay?: string; clsModal?: string; content?: (props: $Modal) => JSX.Element; header?: (props: $Modal) => JSX.Element; }; action: { onToggle: () => void; }; };
export default function Modal(props: $Props) {
const { set, action } = props;
const {} = useContext(ModalCtx);
if (!set?.open) {
return null;
}
return ReactDOM.createPortal(
<div className={cx(styles.overlay, set?.clsOverlay)} onClick={set?.isCloseOutside ? action?.onToggle : undefined}>
<div className={cx(styles.modal, set?.clsModal)} onClick={onStopPrpg}>
{set?.header?.({ onToggle: action.onToggle })}
{set.content?.({ onToggle: action.onToggle })}
</div>
</div>,
document.body
);
}
const onStopPrpg = (event: React.MouseEvent<HTMLDivElement, MouseEvent>) => {
event.stopPropagation();
event.preventDefault();
};
3. Tạo file SCSS cho modal
Cuối cùng, chúng ta cần tạo file SCSS để định dạng cho modal.
scss
.overlay {
position: fixed;
width: 100vw;
height: 100vh;
top: 0;
display: flex;
align-items: center;
justify-content: center;
.modal {
background-color: lightblue;
display: flex;
flex-direction: column;
width: fit-content;
border-radius: 0.5rem;
padding: 1rem;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
.header {
display: flex;
}
}
}
Kết luận
Với các bước hướng dẫn trên, bạn đã có thể tạo một modal đơn giản và dễ dàng tùy chỉnh trong ứng dụng Next.js 14 của mình. Hãy tuỳ chỉnh styles theo ý thích để tạo điểm nhấn cho giao diện của bạn. Chúng tôi sẽ tiếp tục với phần Dropbox trong bài viết tiếp theo.
source: viblo