Using React and Three.js in an Interactive Way in the Browser
Objective
This tutorial describes how to use Three.js and React in an interactive way in the browser. By the end of this short tutorial you will be able to update a Three.js scene on a web app to reflect the inputs provided in a form so that a user can update the scene from the browser. In other words, you will be able to change the cube’s dimensions in the browser. This tutorial will assume that you have a basic understanding of how state and props work in React.
Motivation
Three.js is a powerful library for creating animations, but the resources for making it interactive in the browser are limited. The classic Three.js tutorial teaches you how to make an animation of a spinning cube. I wanted a way to model a 3D shape and then be able to change its dimensions in the browser.
Before We Start
Two important components of the technologies being used that you need to understand are:
- The React Lifecycle
- The Three.js scene and its objects made with geometries and meshes
Starting Point
To start you will need to install the React and Three libraries by running npm install react and npm install three in the terminal of your project folder.
Then create a main.js file and a Shape_Form.js.
To integrate Three.js with React, use a React class component in the main.js file with different methods to:
- Set up the scene
- Add the scene objects
- Start the scene.
(this great tutorial written by Alexander Solovyev is a great place to start.).
Next, create class components for both the three.js scene and the form for inputting the shape information. Then render both of those components in a parent container class component. Put the three.js app class and the container class in the main.js file and then create a separate Shape_Form.js file for the form. Below is the skeleton code for these classes. The shape form has three fields for inputting shape length, shape width, and shape height.
main.js
Shape_Form.js
Adding State
To start we will add the shape’s length, width, and height to state in the constructor of the ShapeForm component. In order to change the shape’s length, width and height using three.js we need to pass them as props to the App component. Because the ShapeForm component is not a child of the App component we need to pass the props to their shared parent container component using a callback. Once the props have been passed to the parent component, we can create the shape geometry with three.js in the App component. If you are unfamiliar with lifting state up you can read about it in the React docs here. We will set state in the OnShapeChange method in the Container component and then call that method on props in the handleSubmit method of the ShapeForm component.
Below is the code with the state and props added and the Three.js methods for creating the scene. The shape will not update properly at this point when the submit button is pressed, but the state will.
main.js
Shape_Form.js
Adding componentDidUpdate to the React Lifecycle
The key to making the scene responsive to the change in state is adding the componentDidUpdate method to the App component. componentDidMount creates the canvas/scene, which we only want to do once. After that initial scene is created by componentDidMount we only want to update certain aspects of the scene and not create a whole new scene.
In order to get the shape to change size in the browser with the componentDidUpdate method, first we need to clear the scene with the .clear() method on the three.js scene to get rid of the existing wrongly sized shape. Then we need to call the addCustomSceneObjects() method that we created on the App component to add a new shape with the new size state on props. Below is the componentDidUpdate method that needs to be added under the componentDidMount method on the App class component.
main.js
Now you can add more state and inputs to the form and watch your shape and scene change from the browser!
The full code can be found here.