-
Notifications
You must be signed in to change notification settings - Fork 2
Description
In React apps, it is a common practice to have context providers for things like theming components, setting up data fetching, etc.
Currently, slots are rendered using createRoot which creates a completely separate tree without access to an app's providers. This means that when rendering the component in DataTables, it may be unstyled, or may not have access to making API calls, etc.
createPortal solves this problem by rendering the element in a different physical location but retaining it in React's internal tree.
(I started working on a PR for this but couldn't immediately test the slot caching, so decided to toss it in an issue for now. I'll try to come back to it as time allows but if someone else beats me to this, that's fine too.)
A quick example when using Tanstack Query:
function ToggleFlaggedButton({ reportId, entryId, isFlagged }) {
const { mutateAsync } = useMutation({
mutationFn: async () => {
const response = await fetch('/api/toggle-flagged', {
method: 'POST',
body: JSON.stringify({ reportId, entryId }),
headers: { 'Content-Type': 'application/json' },
});
if (!response.ok) {
throw new Error('Something went wrong.');
}
return await response.json();
}
});
const onClick = () => {
const action = mutateAsync({isFlagged: !isFlagged});
toast.promise(action, {
loading: 'Toggling flagged...',
success: `The entry is now ${!isFlagged ? 'flagged' : 'unflagged'}.`,
error: 'There was an error toggling the flagged status.'
});
}
return (
<div onClick={onClick} className={'inline-block cursor-pointer'} title={isFlagged ? 'Unflag Entry' : 'Flag Entry'}>{isFlagged ? <FaFlag/> : <FaRegFlag/>}</div>
)
}Table slot usage:
const slots = {
// Flagged
1: (data, row) => {
return <ToggleFlaggedButton reportId={reportId} entryId={row.id} isFlagged={data} />
},
];
<DataTable slots={slots} ...