On routes/index.tsx
I have:
import GrandChildComponent from "../components/GrandChildComponent.tsx";
import { Username } from "./context.ts";
export default function App() {
return (
<Username.Provider value="Bob">
<GrandChildComponent />
</Username.Provider>
)
}
On ./context.ts
I have:
import { createContext } from 'preact'
export const Username = createContext('alice')
If on components/GrandChildComponent.tsx
I use:
import { Username } from "../context.ts";
export default function GrandChildComponent(){
return (
<Username.Consumer>
{username => (
<span>{username}</span>
)}
</Username.Consumer>
)
}
then the result is Bob
as expected. But if I move GrandChildComponent
to the islands
folder then the result is Alice
.
This still happens if I use the useContext
hook:
import { useContext } from "preact/hooks";
import { Username } from "../context.ts";
export default function GrandChildComponent(){
const username = useContext(Username)
return <span>{username}</span>
}
Why can't context work in client? In my case I need to read a config file and pass the data to the client to process, so the provider needs to be on server and the consumer needs to be on client.
Fresh maintainer here:
Sharing data from the server with an island in the browser through context is not supported in Fresh (see https://github.com/denoland/fresh/issues/983 ). The only way to share data in Fresh from the server with an island is via props.
The reason why this doesn't work is that an island re-renders once the browser received the initial HTML. But because the context provider only ever existed on the server, not in the browser, it will fall back to the default value.