React 'Reporting Filter' Shared State Example
Shared State example of a 'Reporting Filter' React form with the agent using hooks.
// FilterPanel.tsx
import { useEffect, useRef, useState } from "react";
type FilterState = {
location: string; // e.g., "NYC"
account: string; // e.g., "Acme Inc"
};
interface Props {
agentKey: string;
initial?: Partial<FilterState>;
}
export default function FilterPanel({ agentKey, initial }: Props) {
const [filters, setFilters] = useState<FilterState>({
location: initial?.location ?? "",
account: initial?.account ?? "",
});
const agentRef = useRef<any | null>(null);
const stateKey = "filters_panel";
const stateDescription = `
type FilterState = {
location: string; // e.g., "NYC"
account: string; // e.g., "Acme Inc"
};
interface Props {
agentKey: string;
initial?: Partial<FilterState>;
}`;
useEffect(() => {
agentRef.current = (window as any).eucera?.agent(agentKey);
const handleStateChange = (key: string, nextState: unknown) => {
if (key === stateKey) setFilters(nextState as FilterState);
};
// initial sync
agentRef.current?.shareState(stateKey, filters, handleStateChange, stateDescription);
return () => {
agentRef.current?.clearState(stateKey);
agentRef.current = null;
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [agentKey]);
const updateField = <K extends keyof FilterState>(k: K, v: FilterState[K]) => {
const next = { ...filters, [k]: v };
setFilters(next);
agentRef.current?.shareState(stateKey, next);
};
const LOCATIONS = ["NYC", "London", "Tel Aviv", "Remote"];
const ACCOUNTS = ["Acme Inc", "Globex", "Initech", "Umbrella"];
return (
<div style={{ display: "grid", gap: 12, maxWidth: 360 }}>
<label>
Location
<select
value={filters.location}
onChange={(e) => updateField("location", e.target.value)}
>
<option value="">Any</option>
{LOCATIONS.map((loc) => (
<option key={loc} value={loc}>{loc}</option>
))}
</select>
</label>
<label>
Account
<select
value={filters.account}
onChange={(e) => updateField("account", e.target.value)}
>
<option value="">Any</option>
{ACCOUNTS.map((a) => (
<option key={a} value={a}>{a}</option>
))}
</select>
</label>
<small>
{/* The agent now has a fresh snapshot at state key "filters_panel". */}
Current: {JSON.stringify(filters)}
</small>
</div>
);
}
Updated 8 days ago