preact-render-to-string
preact-render-to-string copied to clipboard
Context and useState for inter-component state such as CSS for <head>
This is likely a basic misunderstanding, though I've read a lot of tickets and tried a lot of code.
I'm working on Preact as an 11ty template language. I'd like a way for subcomponents to add CSS to <head>, as well as some other uses of state during SSR.
preact-render-to-string has some support for context and hooks. I tried this:
import { createContext } from "preact";
import { useContext, useState } from "preact/hooks";
export const MyContext = createContext();
export function Child() {
const { value, setValue } = useContext(MyContext);
// Changing the state has no effect, neither here
// in child nor in parent.
setValue(33);
return (
<div>
<p>Value in child: {value}</p>
</div>
);
}
export function App() {
const [value, setValue] = useState(99);
return (
<MyContext.Provider value={{ value, setValue }}>
<div>
<Child />
<p>Value in parent: {value}</p>
</div>
</MyContext.Provider>
);
}
In a Vitest test:
it("should render", async () => {
const app = <App/>;
await renderToStringAsync(<App />);
const result = await renderToStringAsync(app);
expect(result).toContain("count is 33");
});
It still renders with the original 99. Do I need to trigger some lifecycle method? Render first with Preact, then render to a string? (I saw an experiment from @developit using undom.)