Skip to content

Instantly share code, notes, and snippets.

@ejangi
Created June 24, 2021 23:38
Show Gist options
  • Save ejangi/89ead7fa843fe5cae081cbc8db0043ff to your computer and use it in GitHub Desktop.
Save ejangi/89ead7fa843fe5cae081cbc8db0043ff to your computer and use it in GitHub Desktop.
An example of exposing component methods to parent component in React and Next JS
import { useState, useRef, useEffect, forwardRef, useImperativeHandle } from 'react';
import Button from '@material-ui/core/Button';
import Dialog from '@material-ui/core/Dialog';
import DialogActions from '@material-ui/core/DialogActions';
import DialogContent from '@material-ui/core/DialogContent';
import DialogContentText from '@material-ui/core/DialogContentText';
import DialogTitle from '@material-ui/core/DialogTitle';
/*
USAGE:
export default function MyComponent() {
const modalRef = useRef();
const handleModalOpen = () => {
modalRef.current.handleClickOpen();
};
return(
<>
<Button onClick={handleModalOpen}>Open</Button>
<Modal
ref={modalRef}
title="Hello world"
actions={<Button color="primary">Hi there!</Button>}
>
<Typography variant="body1">What would you like to do?</Typography>
</Modal>
</>
)
}
*/
export default forwardRef(function Modal(props, ref) {
const {
title,
children,
actions,
} = props;
const descriptionElementRef = useRef(null);
const [open, setOpen] = useState(false);
const [modalTitle, setModalTitle] = useState(title);
const [modalDescription, setModalDescription] = useState(children);
// These functions are available externally as well:
useImperativeHandle(ref, () => ({
setTitle: (newTitle) => {
setModalTitle(newTitle);
},
setDescription: (newDescription) => {
setModalDescription(newDescription);
},
handleClickOpen: () => {
setOpen(true);
},
handleClose: () => {
setOpen(false);
},
}));
const handleModalOpen = () => {
ref.current.handleClickOpen();
};
const handleModalClose = () => {
ref.current.handleClose();
}
useEffect(() => {
if (open) {
const { current: descriptionElement } = descriptionElementRef;
if (descriptionElement !== null) {
descriptionElement.focus();
}
}
}, [open]);
return (
<div>
<Dialog
open={open}
onClose={handleModalClose}
scroll="paper"
aria-labelledby="scroll-dialog-title"
aria-describedby="scroll-dialog-description"
>
<DialogTitle id="scroll-dialog-title">{modalTitle}</DialogTitle>
<DialogContent dividers={true}>
<DialogContentText
id="scroll-dialog-description"
ref={descriptionElementRef}
tabIndex={-1}
>
{(modalDescription)}
</DialogContentText>
</DialogContent>
<DialogActions>
<Button onClick={handleModalClose}>
Cancel
</Button>
{actions}
</DialogActions>
</Dialog>
</div>
);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment