I need to implement a reusable modal. I have basically two implementations in my mind.
Handle the modal visibility in the parent state. Then I'll have to pass the state setter into the modal component as I'll always have a button inside the modal to close the modal.
const Modal = (props) => {
return (
<div>
<button onClick={() => props.setVisibility(false)}>Cancel</button>
</div>
);
};
export default function App() {
const [showModal, setShowModal] = useState(false);
return (
<div className="App">
<button onClick={() => setShowModal((p) => !p)}>Toggle Modal</button>
{showModal && <Modal setShowModal={setShowModal} />}
</div>
);
}
Handle the modal visibility in the modal component itself, but expose a function to show/hide the modal using an imperativeHandle.
const Modal = React.forwardRef((props, ref) => {
const [showModal, setShowModal] = useState(false);
useImperativeHandle(ref, () => ({
hide: () => setShowModal(false),
show: () => setShowModal(true),
toggle: () => setShowModal((p) => !p)
}));
if (!showModal) return null;
return (
<div>
<button onClick={() => setShowModal(false)}>Cancel</button>
</div>
);
});
export default function App() {
const modal = useRef();
return (
<div className="App">
<button onClick={() => modal.current.toggle()}>Toggle Modal</button>
<Modal ref={modal} />
</div>
);
}
I prefer the second one, as I think it looks cleaner, without a bunch of states polluting the parent component(there will be multiple modals on one page). The toggle function is only there for the example, I'll only ever need the show and hide functions. Plus, the visibility of the modal is a property of the modal, and I feel like the modal should be the component that is handling it. But I've heard people and even the react docs saying
imperative code using refs should be avoided in most cases
So, even though I think this is an acceptable use of refs, that's what's holding me back. I want to know,
which of the two is the react way of doing this
are there any differences in performance between the two ways
are there possibilities of bugs occurring if I decide to use refs