emotion
emotion copied to clipboard
Can't clear emotion cache.
Current behavior:
injectGlobal
from @emotion/css
retains injections from another emotion server!
To reproduce:
It's a server-side rendered app.
Render code:
import { getMarkupFromTree } from '@apollo/client/react/ssr';
import { cache as emotionCache, injectGlobal } from '@emotion/css';
import { CacheProvider as EmotionCacheProvider } from '@emotion/react';
import createEmotionServer from '@emotion/server/create-instance';
import type { NextFunction, Request, Response } from 'express';
import type { FC } from 'react';
import { renderToString } from 'react-dom/server';
const App: FC<{ bgColor: string }> = ({ bgColor }) => {
injectGlobal(`body { background-color: ${bgColor}; }`);
return <>Dummy App</>;
};
export async function renderDummy(
request: Request,
response: Response,
next: NextFunction
): Promise<void> {
const currentUrl = new URL(request.url, `${request.protocol}://${request.hostname}`);
const bgColor = currentUrl.searchParams.get('background-color') ?? 'blue';
const { extractCriticalToChunks, constructStyleTagsFromChunks } =
createEmotionServer(emotionCache);
const reactMarkup = (
<EmotionCacheProvider value={emotionCache}>
<App bgColor={bgColor} />
</EmotionCacheProvider>
);
const markup = await getMarkupFromTree({
tree: reactMarkup,
renderFunction: renderToString,
});
const styleChunks = extractCriticalToChunks(markup);
const styles = styleChunks.styles.map(style => {
return { ...style, key: 'my-app' };
});
const emotionStyleTags = constructStyleTagsFromChunks({
html: markup,
styles,
});
const output = `<!DOCTYPE html>
<head>
${emotionStyleTags}
</head>
<html>
<body>
${markup}
</body>
</html>
`;
response.setHeader('Content-Type', 'text/html');
response.write(output);
response.status(200);
response.end();
}
Calling http://localhost will render text on blue background (because that's the default). Calling http://localhost/?background-color=yellow will render a yellow background Calling http://localhost again will keep rendering yellow background even though it should be blue!
Expected behavior:
It should render the background compatible with the the current invocation, and not use state cache state for global injection.
Note that I tried to make a new cache every render, i.e. const emotionCache = createEmotionCache({ key: 'marketing-web-emotion' });
but that just doesn't work. No warnings, errors, nor content.
If nothing else, it would be nice to be able to reset the cache, but that also doesn't seem possible. I tried inspecting cache's inserted
and registered
properties, but they don't contain globally injected styles.
Environment information:
-
react
version: 18.2 -
@emotion/react
version: 11.9.0