Using vtk.js with React

This is a quickstart tutorial for using vtk.js with React.

Initialize your project

Use npx create-react-app my-vtkjs-app, yarn create react-app my-vtkjs-app, or npm init react-app to initialize your project.
For this tutorial, we will use yarn.

$ yarn create react-app my-vtkjs-app
$ cd my-vtkjs-app
$ ls
node_modules/ package.json public/ README.md src/ yarn.lock

Now install vtk.js as a dependency.

$ yarn add @kitware/vtk.js

Using vtk.js in your app

To add a minimal vtk.js example to your app, replace src/App.js with the following contents.

src/App.js
import { useState, useRef, useEffect } from 'react';

import '@kitware/vtk.js/Rendering/Profiles/Geometry';

import vtkFullScreenRenderWindow from '@kitware/vtk.js/Rendering/Misc/FullScreenRenderWindow';

import vtkActor from '@kitware/vtk.js/Rendering/Core/Actor';
import vtkMapper from '@kitware/vtk.js/Rendering/Core/Mapper';
import vtkConeSource from '@kitware/vtk.js/Filters/Sources/ConeSource';

function App() {
const vtkContainerRef = useRef(null);
const context = useRef(null);
const [coneResolution, setConeResolution] = useState(6);
const [representation, setRepresentation] = useState(2);

useEffect(() => {
if (!context.current) {
const fullScreenRenderer = vtkFullScreenRenderWindow.newInstance({
rootContainer: vtkContainerRef.current,
});
const coneSource = vtkConeSource.newInstance({ height: 1.0 });

const mapper = vtkMapper.newInstance();
mapper.setInputConnection(coneSource.getOutputPort());

const actor = vtkActor.newInstance();
actor.setMapper(mapper);

const renderer = fullScreenRenderer.getRenderer();
const renderWindow = fullScreenRenderer.getRenderWindow();

renderer.addActor(actor);
renderer.resetCamera();
renderWindow.render();

context.current = {
fullScreenRenderer,
renderWindow,
renderer,
coneSource,
actor,
mapper,
};
}

return () => {
if (context.current) {
const { fullScreenRenderer, coneSource, actor, mapper } = context.current;
actor.delete();
mapper.delete();
coneSource.delete();
fullScreenRenderer.delete();
context.current = null;
}
};
}, [vtkContainerRef]);

useEffect(() => {
if (context.current) {
const { coneSource, renderWindow } = context.current;
coneSource.setResolution(coneResolution);
renderWindow.render();
}
}, [coneResolution]);

useEffect(() => {
if (context.current) {
const { actor, renderWindow } = context.current;
actor.getProperty().setRepresentation(representation);
renderWindow.render();
}
}, [representation]);

return (
<div>
<div ref={vtkContainerRef} />
<table
style={{
position: 'absolute',
top: '25px',
left: '25px',
background: 'white',
padding: '12px',
}}
>
<tbody>
<tr>
<td>
<select
value={representation}
style={{ width: '100%' }}
onInput={(ev) => setRepresentation(Number(ev.target.value))}
>
<option value="0">Points</option>
<option value="1">Wireframe</option>
<option value="2">Surface</option>
</select>
</td>
</tr>
<tr>
<td>
<input
type="range"
min="4"
max="80"
value={coneResolution}
onChange={(ev) => setConeResolution(Number(ev.target.value))}
/>
</td>
</tr>
</tbody>
</table>
</div>
);
}

export default App;

Running the app

You can run the app using the project’s built-in dev server.

$ yarn start

Navigate to http://localhost:3000, and you should have an interactive 3D visualization of a cone, similar to the SimpleCone example.

Where to go next

Check out the tutorials, or if you know what you want but need API docs, check out the API.