useImperativeHandle() React 후크가 있는 모달 대화 상자 표시
24886 단어 webdevtypescriptreactjavascript
Dialog
구성 요소를 예로 들어 open: boolean
React prop을 열림/닫힘 상태를 관리하는 방법으로 사용합니다. Material UIdocumentation에서 다음과 유사한 사용 예를 찾을 수 있습니다.import * as React from "react";
import { Button, Container, Dialog, DialogActions, DialogContent, DialogTitle } from "@mui/material";
export function Example(): JSX.Element {
const [open, setOpen] = React.useState(false);
const handleOpen = React.useCallback(() => setOpen(true), []);
const handleClose = React.useCallback(() => setOpen(false), []);
const handleAction = React.useCallback(() => { ... }, []);
return (
<Container>
<Button onClick={handleOpen}>Open Dialog</Button>
<Dialog open={state.open} onClose={handleClose}>
<DialogTitle>...</DialogTitle>
<DialogContent>
...
</DialogContent>
<DialogActions>
<Button onClick={handleClose}>Cancel</Button>
<Button onClick={handleAction}>OK</Button>
</DialogActions>
</Dialog>
</Container>
);
}
원래 예에서는 대화 상자가 제자리에서 사용됩니다. 일반적으로 독립 실행형 구성 요소에서 대화 상자를 추출하려고 합니다. 예를 들면 다음과 같습니다.
import * as React from "react";
import { Button, Container, Dialog, DialogActions, DialogContent, DialogProps, DialogTitle } from "@mui/material";
export function ConfirmDialog(props: ConfirmDialogProps): JSX.Element {
const [state, setState] = ...
const handleClose = ...
const handleConfirm = ...
return (
<Dialog open={state.open} {...props}>
<DialogTitle>...</DialogTitle>
<DialogContent>
...
</DialogContent>
<DialogActions>
<Button onClick={handleClose}>Cancel</Button>
<Button onClick={handleConfirm}>OK</Button>
</DialogActions>
</Dialog>
);
}
export type ConfirmDialogProps = Omit<DialogProps, "open">;
그런 다음 원래 예를 다음과 같이 줄일 수 있습니다.
import * as React from "react";
import { ConfirmDialog } from "../dialogs/ConfirmDialog.js";
export function Example(): JSX.Element {
const handleOpen = ...
const handleAction = ...
return (
<Container>
<Button onClick={handleOpen}>Open Dialog</Button>
<ConfirmDialog onConfirm={handleAction} />
</Container>
);
}
상태를 내부에서 관리할 필요 없이 대화 상자를 사용할 수 있다면 코드가 멋지고 깨끗해 보일 것입니다.
이를 구현하는 방법에는 여러 가지가 있습니다. 최상위
DialogProvider
구성 요소 + useDialog(...)
React 후크를 도입하여 대화 인스턴스에서 사용할 수 있는 dialogRef.current?.open()
메서드를 사용하여 열 수 있도록 대화 자체에 명령형 핸들러를 추가할 수 있습니다.import * as React from "react";
import { ConfirmDialog } from "../dialogs/ConfirmDialog.js";
export function Example(): JSX.Element {
const dialogRef = React.useRef<DialogElement>(null);
const handleOpen = React.useCallback(() = dialogRef.current?.open(), []);
const handleAction = ...
return (
<Container>
<Button onClick={handleOpen}>Open Dialog</Button>
<ConfirmDialog ref={dialogRef} onConfirm={handleAction} />
</Container>
);
}
이제
.open()
, useImeprativeHandle(ref, ...)
React 후크로 구현된 useState()
메서드를 포함하여 이 대화 상자의 구현이 어떻게 보이는지 살펴보겠습니다.import * as React from "react";
import { Button, Dialog, DialogActions, DialogContent, DialogProps, DialogTitle } from "@mui/material";
export const ConfirmDialog = React.forwardRef<
DialogElement,
ConfirmDialogProps
>(function ConfirmDialog(props, ref): JSX.Element {
const { onClose, onConfirm, ...other } = props;
const [state, setState] = React.useState<State>({ open: false });
const handleClose = useHandleClose(setState, onClose);
const handleConfirm = useHandleConfirm(setState, onConfirm);
React.useImperativeHandle(ref, () => ({
open() {
setState({ open: true });
},
}));
return (
<Dialog open={state.open} onClose={handleClose} {...other}>
<DialogTitle>...</DialogTitle>
<DialogContent>...</DialogContent>
<DialogActions>
<Button onClick={handleClose}>Cancel</Button>
<Button onClick={handleConfirm}>OK</Button>
</DialogActions>
</Dialog>
);
});
function useHandleClose(setState: SetState, handleClose?: CloseHandler) {
return React.useCallback<CloseHandler>(function (event, reason) {
setState({ open: false });
handleClose?.(event, reason ?? "backdropClick");
}, []);
}
function useHandleConfirm(setState: SetState, handleConfirm?: ConfirmHandler) {
return React.useCallback(async function () {
await handleConfirm?.();
setState({ open: false });
}, []);
}
type State = { open: boolean; error?: Error };
type SetState = React.Dispatch<React.SetStateAction<State>>;
type CloseHandler = NonNullable<DialogProps["onClose"]>;
type ConfirmHandler = () => Promise<void> | void;
export type DialogElement = { open: () => void };
export type ConfirmDialogProps = Omit<DialogProps, "open"> & {
onConfirm?: ConfirmHandler;
};
이 접근 방식에는 장단점이 있지만 좋은 점은 완전히 독립적이며 외부 상태 관리 솔루션에 의존하지 않는다는 것입니다.
https://github.com/kriasoft/react-starter-kit/discussions/2004
Reference
이 문제에 관하여(useImperativeHandle() React 후크가 있는 모달 대화 상자 표시), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/koistya/showing-a-modal-dialog-useimperativehandle-react-hook-2cb텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)