I currently have a canvas that covers the entire screen that renders a torus on the home page to a View
that tracks to a div
in the home page. However, when I click on my navbar to another page and the route changes, the torus is still there even when the div
that the View
is tracking disappears. The HTML elements position themselves as if the div
is not there and upon refreshing the page, the torus disappears.
Torus appearing correctly on the home page This is the torus appear correctly on the home page. See that the "Home" text appears underneath it
Torus staying there even though route changed This is the torus staying there even when the route changed. See that the "Syllabus" text appears at the top
Refreshing the page, the torus is correctly not there on the syllabus page When the page is refreshed, the torus disappears which is the intended response.
I making the View
change depending on the route by inserting a <Route>
inside the Canvas, but I couldn't do it as it wasn't a Three component.
I also tried to use useLocation()
and the useEffect()
components to update the position of the torus repeatedly, moving my canvas into its own element and nesting it inside the Routes component. However, I could not find a way to pass multiple references down to the Canvas.
I suspect the issue is because the canvas does not get rerendered when the route changes, however I'm not sure how to force a rerender.
Here is my code
const ref = useRef()
const splashView = useRef()
return (
<div>
<BrowserRouter>
<div ref={ref}>
<Navbar/>
<Routes>
<Route index element={<Home ref={splashView}/>}/>
<Route path="/home" element={<Home ref={splashView}/>}/>
<Route path="/syllabus" element={<Syllabus/>}/>
</Routes>
</div>
</BrowserRouter>
<Canvas eventSource={ref} className={styles.canvas}>
{/* --------------Home Page-------------- */}
<View track={splashView}>
<ambientLight intensity={0.1} />
<directionalLight color="red" position={[0, 0, 5]} />
<mesh>
<torusGeometry/>
<meshStandardMaterial />
</mesh>
</View>
</Canvas>
</div>
);
}
After passing the reference into the component, I use forwardRef()
to forward it to a div. I am using react-router-dom for routing.
I suspect you could just render the Canvas
with the Home
component on its route, and redirect the root index route to "/home"
so the code is more DRY (or vice-versa).
const ref = useRef()
const splashView = useRef()
return (
<div>
<BrowserRouter>
<div ref={ref}>
<Navbar />
<Routes>
<Route index element={<Navigate to="/home" replace />} />
<Route
path="/home"
element={(
<>
<Home ref={splashView} />
<Canvas eventSource={ref} className={styles.canvas}>
<View track={splashView}>
<ambientLight intensity={0.1} />
<directionalLight color="red" position={[0, 0, 5]} />
<mesh>
<torusGeometry />
<meshStandardMaterial />
</mesh>
</View>
</Canvas>
</>
)}
/>
<Route path="/syllabus" element={<Syllabus />} />
</Routes>
</div>
</BrowserRouter>
</div>
);