React Component
We provide a React wrapper to prevent common issues and mistakes associated with using the perspective-viewer web component in the context of React.
Before trying this example, please take a look at how to bootstrap perspective.
A simple example:
import * as React from "react";
import { createRoot } from "react-dom/client";
import { PerspectiveViewer } from "@finos/perspective-react";
import "@finos/perspective-viewer/dist/css/themes.css";
import "./index.css";
interface ToolbarState {
mounted: boolean;
table?: Promise<psp.Table>;
config: pspViewer.ViewerConfigUpdate;
}
const App: React.FC = () => {
const [state, setState] = React.useState<ToolbarState>(() => ({
mounted: true,
table: createNewSuperstoreTable(),
config: { ...CONFIG },
}));
React.useEffect(() => {
return () => {
state.table?.then((table) => table?.delete({ lazy: true }));
};
}, []);
const onClickOverwrite = () => {
state.table?.then((table) => table?.delete({ lazy: true }));
const table = createNewSuperstoreTable();
setState({ ...state, table });
};
const onClickDelete = () => {
state.table?.then((table) => table?.delete({ lazy: true }));
setState({ ...state, table: undefined });
};
const onClickToggleMount = () =>
setState((old) => ({ ...old, mounted: !state.mounted }));
const onConfigUpdate = (config: pspViewer.ViewerConfigUpdate) => {
console.log("Config Update Event", config);
setState({ ...state, config });
};
const onClick = (detail: pspViewer.PerspectiveClickEventDetail) => {
console.log("Click Event,", detail);
};
const onSelect = (detail: pspViewer.PerspectiveSelectEventDetail) => {
console.log("Select Event", detail);
};
return (
<div className="container">
<div className="toolbar">
<button onClick={onClickToggleMount}>Toggle Mount</button>
<button onClick={onClickOverwrite}>Overwrite Superstore</button>
<button onClick={onClickDelete}>Delete Table</button>
</div>
{state.mounted && (
<>
<PerspectiveViewer table={state.table} />
<PerspectiveViewer
className="my-perspective-viewer"
table={state.table}
config={state.config}
onClick={onClick}
onSelect={onSelect}
onConfigUpdate={onConfigUpdate}
/>
</>
)}
</div>
);
};
createRoot(document.getElementById("root")!).render(<App />);
This adds a perspective table to the provider at the root of the app and allows us to create viewers referencing those tables anywhere within that context. Any views or viewers associated with the React component are automatically cleaned up as part of the lifecycle of the component, but tables are still the responsibility of the caller to cleanup currently.