Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ref callbacks & this.mount - reactJS

I was reading the top answer to this question.

How to connect Threejs to React?

Someone provided this great example of using threejs in react:

import React, { Component } from 'react'
import * as THREE from 'three'

class Scene extends Component {
constructor(props) {
super(props)

this.start = this.start.bind(this)
this.stop = this.stop.bind(this)
this.animate = this.animate.bind(this)
}

componentDidMount() {
const width = this.mount.clientWidth
const height = this.mount.clientHeight

const scene = new THREE.Scene()
const camera = new THREE.PerspectiveCamera(
  75,
  width / height,
  0.1,
  1000
)
const renderer = new THREE.WebGLRenderer({ antialias: true })
const geometry = new THREE.BoxGeometry(1, 1, 1)
const material = new THREE.MeshBasicMaterial({ color: '#433F81' })
const cube = new THREE.Mesh(geometry, material)

camera.position.z = 4
scene.add(cube)
renderer.setClearColor('#000000')
renderer.setSize(width, height)

this.scene = scene
this.camera = camera
this.renderer = renderer
this.material = material
this.cube = cube

this.mount.appendChild(this.renderer.domElement)
this.start()
}

componentWillUnmount() {
this.stop()
this.mount.removeChild(this.renderer.domElement)
}

start() {
if (!this.frameId) {
  this.frameId = requestAnimationFrame(this.animate)
}
}

stop() {
  cancelAnimationFrame(this.frameId)
}

animate() {
this.cube.rotation.x += 0.01
this.cube.rotation.y += 0.01

this.renderScene()
this.frameId = window.requestAnimationFrame(this.animate)
}

renderScene() {
  this.renderer.render(this.scene, this.camera)
}

render() {
return (
  <div
    style={{ width: '400px', height: '400px' }}
    ref={(mount) => { this.mount = mount }}
  />
)
}
}

export default Scene

I do not understand this.mount . What is this.mount? It seems to be used to access client width and client height. And what is the ref callback function ref={(mount) => { this.mount = mount }} doing?

I did some research and found that ref callbacks are called after the component mounts, they can be used for passing state from parents to children, but they should only be used when necessary. I got all that from the docs.

I plan on modifying this script for my own purpose so understanding this.mount and the ref callback would be really helpful. TIA

like image 843
Joey Gough Avatar asked Mar 24 '18 21:03

Joey Gough


1 Answers

Check the docs - React Refs and the DOM (emphasis mine):

When the ref attribute is used on an HTML element, the ref callback receives the underlying DOM element as its argument.

So in:

  render() {
    return (
      <div
        style={{ width: '400px', height: '400px' }}
        ref={(mount) => { this.mount = mount }}
      />
    )
  }

this.mount will hold a reference to the actual <div> the component is mounted to.

It is important to notice that this.mount will only exist after the component is mounted. That is why all logic that uses this.mount is in componentDidMount() or after, which is triggered only after the component is mounted:

componentDidMount() is invoked immediately after a component is mounted. Initialization that requires DOM nodes should go here. If you need to load data from a remote endpoint, this is a good place to instantiate the network request.

like image 88
acdcjunior Avatar answered Sep 28 '22 09:09

acdcjunior