I'm trying to do a memoize Modal and I have a problem here.
When I change input I dont need to re-render the Modal component.
For example:
Modal.tsx looks like this:
import React from "react";
import { StyledModalContent, StyledModalWrapper, AbsoluteCenter } from "../../css";
interface ModalProps {
open: boolean;
onClose: () => void;
children: React.ReactNode
};
const ModalView: React.FC<ModalProps> = ({ open, onClose, children }) => {
console.log("modal rendered");
return (
<StyledModalWrapper style={{ textAlign: "center", display: open ? "block" : "none" }}>
<AbsoluteCenter>
<StyledModalContent>
<button
style={{
position: "absolute",
cursor: "pointer",
top: -10,
right: -10,
width: 40,
height: 40,
border: 'none',
boxShadow: '0 10px 10px 0 rgba(0, 0, 0, 0.07)',
backgroundColor: '#ffffff',
borderRadius: 20,
color: '#ba3c4d',
fontSize: 18
}}
onClick={onClose}
>
X
</button>
{open && children}
</StyledModalContent>
</AbsoluteCenter>
</StyledModalWrapper>
);
};
export default React.memo(ModalView);
Here is an example of how I wrap it.
import React from 'react'
import Modal from './modal';
const App: React.FC<any> = (props: any) => {
const [test, setTest] = React.useState("");
const [openCreateChannelDialog, setOpenCreateChannelDialog] = React.useState(false);
const hideCreateModalDialog = React.useCallback(() => {
setOpenCreateChannelDialog(false);
}, []);
return (
<>
<input type="text" value={test} onChange={(e) => setTest(e.target.value)} />
<button onClick={() => setOpenCreateChannelDialog(true)}>Create channel</button>
<Modal
open={openCreateChannelDialog}
onClose={hideCreateModalDialog}
children={<CreateChannel onClose={hideCreateModalDialog} />}
/>
</>
};
I know, Modal re-rendered because children reference created every time when App component re-renders (when I change an input text).
Know I'm interested, if I wrap <CreateChannel onClose={hideCreateModalDialog} /> inside React.useMemo() hook
For example:
const MemoizedCreateChannel = React.useMemo(() => {
return <CreateChannel onClose={hideCreateModalDialog} />
}, [hideCreateModalDialog]);
And change children props inside Modal
from:
children={<CreateChannel onClose={hideCreateModalDialog} />}
to
children={MemoizedCreateChannel}
It works fine, but is it safe? And it is only one solution that tried to memoize a Modal?