react-external-renderer
v0.0.1
Published
`react-external-renderer` is a library that allows you to render any component simply and declaratively using React.
Readme
react-external-renderer
react-external-renderer is a library that allows you to render any component simply and declaratively using React.
Inspired by overlay-kit.
Installation
npm i react-external-rendererimport { createExternalRenderer } from "react-external-renderer";Code Comparison
Before
import { useState } from "react";
function Before() {
const [isOpen, setIsOpen] = useState(false);
return (
<>
<Button onClick={() => setIsOpen(true)}>Open</Button>
{/* We have to put <Dialog/> here */}
<Dialog open={isOpen} onClose={() => setIsOpen(false)} />
</>
);
}After
const { render, Renderer, Debug } = createExternalRenderer();
function After() {
const openDialog = () => {
// Extract the props for readability
const defaultProps = { isOpen: true };
const closedProps = { isOpen: false };
const { rerender } = render(
({ isOpen }) => <Dialog open={isOpen} onClose={() => rerender(closedProps)} />,
defaultProps
);
};
return (
<>
<Button onClick={openDialog}>Open</Button>
{/* You can place <Renderer /> anywhere;
it doesn't need to be in the same component */}
<Renderer />
</>
);
}External Render
const { render, Renderer, Debug } = createExternalRenderer();
function Root() {
return (
<>
<App />
<Renderer />
</>
);
}
function App() {
const openDialog = () => {
const { rerender } = render(
({ isOpen }) => <Dialog open={isOpen} onClose={() => rerender({ isOpen: false })} />,
{ isOpen: true }
);
};
return <Button onClick={openDialog}>Open</Button>;
}More demos can be found in the docs
Avoiding Memory Leaks
You can use react-external-renderer to render anything, but when you call render, you must call remove when you no longer want to rerender.
Using a modal as an example, since a modal might first show an exit animation and then unmount, you can do the following:
/** This is a real-world case using <Modal/> from the antd library */
function App() {
const openDialog = () => {
const { rerender, remove } = render(
({ isOpen }) => {
const close = () => rerender({ isModalOpen: false });
return (
<Modal
open={isOpen}
onOk={close}
onCancel={close}
afterClose={remove} // Add this
/>
);
},
{ isOpen: true }
);
};
return <Button onClick={openDialog}>Open</Button>;
}Since we only want to render the modal once here, when there is no exit animation, you can simply call remove:
function App() {
const openDialog = () => {
const { remove } = render(({ isOpen }) => <Dialog open={isOpen} onClose={remove} />, {
isOpen: true,
});
};
return <Button onClick={openDialog}>Open</Button>;
}