Advanced
React Context
Share state between components without prop drilling
- context
- local state
Key concepts
count
is a server prop, assigned on the LiveView exactly like
the Counter example. React's own createContext/useContext
then shares that value with a nested component with no prop passed
between them — the two mechanisms compose, they don't conflict.
import React, { createContext, useContext } from "react";
import { useLiveReact } from "live_react";
// `count` comes from the server, but only the provider at the top needs to
// know that — everything below reads it from context, with no prop drilling.
const CountContext = createContext<number>(0);
function CountDisplay() {
const count = useContext(CountContext);
return <span className="text-xl">{count}</span>;
}
export function Context({ count }: { count: number }) {
const { pushEvent } = useLiveReact();
return (
<CountContext.Provider value={count}>
<div className="flex items-center gap-6">
<button
className="rounded-md border px-3 py-1"
onClick={() => pushEvent("set_count", { value: count - 1 })}
>
−1
</button>
<CountDisplay />
<button
className="rounded-md border px-3 py-1"
onClick={() => pushEvent("set_count", { value: count + 1 })}
>
+1
</button>
</div>
</CountContext.Provider>
);
}
How it works
Context
wraps its children in a CountContext.Provider
whose value is the server-owned count
prop. Any component
inside that tree — however deeply nested — can call useContext(CountContext)
to read it, without every
component in between having to accept and forward a count
prop it doesn't otherwise need.
Clicking a button still calls pushEvent("set_count", …),
which reaches handle_event/3
and reassigns count
on the server, same as Counter — context describes how a value moves
around inside React, not where it comes from.