Raycasting does not work in React app

I’ve included comments, essentially what I want to do is get Raycasting working. I haven’t attempted it in this distilled codesandbox, but I understand it requires a Vector2 of the mouse position, which I’m storing in the state. However because I have a ‘createWorld’ function that instantiates the scene only once with a useEffect on component mount, the inner ‘animate’ function doesn’t have access to that state.

I’ve update your codesandbox and added raycasting support:

I’m not familiar with React so I can’t tell you why the usage of useState() didn’t work. It’s probably best to ask this question at the React community.

here’s a basic working example for studying the raycaster: https://codesandbox.io/s/reurope-threejs-basic-kiow9

looking at your code, you shouldn’t use setstate at all for mouse input, that will re-render everything on every mousemove. better make a ref

const mouse = useRef([0, 0])

and mutate it in the event mouse.current = [x, y]. fetch these coordinates inside the frameloop. you also should avoid re-creating a new vector every time. the reason why “coords” is stale is because you’re inside a javascript closure, it will only remember the last value because useEffect executes only once , []). the ref would solve that.

but i would suggest you use react-three-fiber if you can: https://codesandbox.io/s/rrppl0y8l4 threejs mostly conflicts with react due to its imperative nature and as for events, there are none, no bubbling, etc. a reconciler is just a different way to express threejs, it is still very much threejs without any hard dependency - but now it’s declarative and managed.

1 Like

Very cool, thanks so much!

1 Like

Thanks @drcmda, I have tried react-three-fiber and I’m really impressed with what you’ve done with it. But if I’m being honest its a bit above my head because the docs point toward Threejs docs, and the method of thinking about how it all fits together is just so different for someone at my level to work out

oh, it’s you!! didn’t realize, should’ve looked at the avatar and the name harder :grinning_face_with_smiling_eyes: anyway, the useRef stuff will solve your problem!

const mouse = useRef([0, 0])

...
  var animate = function() {
      requestAnimationFrame(animate)
      console.log(mouse.current)
...

return <div onMouseMove={e => /* ... */ mouse.current = [x, y]) .... />
1 Like

My first thought was, Paul would answer the shit out of this question if he sees it :sweat_smile:

Hello Kyle!
I was wondering if you were able to get this working? I also am having the same problem, and searching throughout the internet there are very little resources available. I know how to do this in regular HTML/JS/CSS, but React has been kicking me with their weird mouse event handling. Anyways, if yes, could you possibly share the finalized version in another CodeSandbox, please?

1 Like

@David_G Hey mate, just letting you know I’ve seen your reply and I did get it to work. I’ll do a pen for you but the responses helped me out for sure . Are you using useRef?

1 Like

Thank you for the reply.
I am in the process of still learning the components/modules for React, following along with tutorials/reading stackoverflow. I was trying to use onChange(), but that was messing up my program (would not compile/errors galore). I am in the process of making a simple-interactive globe with lat/lon and having them interact with the mouse to produce simple data in a tooltip. I have the lat/lon correctly placed, but the interaction is what I am having difficulty with. I saw an article which uses D3, React, and Three.JS which was done for a Romanian hackathon. In this, he compiles ThreeJS vanilla-style, but uses React for the UI component (which I may end up doing). I was hoping to try and integrate the RayCaster within React, versus having them be operating separately, though updating with the requestAnimationFrame() callback function.