How can i actualize a ref in React?

30 Views Asked by At

I have a problem, i am working with React and, i have a Navbar component, a HomePage and inside HomePage i have another component that is Projects, i have a button in the NavBar that when i press it i want to scrollIntoView to a div inside the Projects component. I use forwardRef in the child component to make it work.

It works fine when i am in Homepage (/home), but if i press it from another component render by other route, (/gamezone) the behavior that i want to do is, first navigate to the HomePage route, then scrollIntoView the project, but here ref is not defined. I understand that i am forwarding the ref of the child only to HomePage, but i dont understand how to make it actualize itself so i can refer to the ref and don't make it undefined when i am calling the function in the GameZone

I tried to generate the Ref in a Context to give it to all routes, also i tried flushSync to make the dom reload and maybe when i navigate to the /home route the ref actualize itself, but i can't make it works

Here is the resumed code:

App.js

  <BrowserRouter>
  <Routes>
  <Route path="/" element={<HomePage />} />
    <Route path="/home" element={<HomePage />} />
    <Route path="/home/game_zone" element={<GameZone />} />
  </Routes>
  </BrowserRouter>

Header

import projects from '../img/project.png'

function Header({handleClickScroll}) {
 return (
      <div className="header">
          <div className="navbar-element" >
             <div className='link-container'>
                 <img className="projects" src={projects} onClick={handleClickScroll}> 
                 </img>
                 PROJECTS
             </div>
          </div>
      </div>
  );
}
      
export default Header;

HomePage

import { useState, useRef  } from 'react';
import { flushSync } from 'react-dom';
import { redirect, useNavigate } from "react-router-dom";
import Header from './Header';
import Projects from './Projects';

function HomePage({props}) {
    const ref = useRef(null);
    const navigate = useNavigate();

    const handleClickScroll = () => {
        if (ref.current) {
            ref.current.scrollIntoView({ behavior: 'smooth' });
        }
        else {
            navigate("/portfolio")
            flushSync(() => {})
            ref.current.scrollIntoView({ behavior: 'smooth' });
        }
    }

  return (   
    <div className="homepage">
        <Header handleClickScroll={() => {handleClickScroll()}}/>
        <div className="content">
        </div>
        <Projects ref={ref}/>      

        <div className='footer'>
        </div>
    </div>
  );
}

export default HomePage;

Projects

import { forwardRef } from 'react';
const Projects = forwardRef( function Projects(props, ref) {


  return (
    <div className="projects-content" id="projects" ref={ref}> 
    </div>
  );
}) 

GameZone

import { useState, useRef } from 'react'
import { flushSync } from 'react-dom';
import { useNavigate } from "react-router-dom";

function GameZone() {
    const ref = useRef();
    const navigate = useNavigate();

    const handleClickScroll = () => {
    if (ref.current) {
        ref.current.scrollIntoView({ behavior: 'smooth' });
    }
    else {
        navigate("/home")
        flushSync(() => {ref.current.scrollIntoView({ behavior: 'smooth' });}) 
    }
    return ( 
      <>
          <div className="gamezone-content">
              <Header handleClickScroll={() => handleClickScroll()}/>
          </div>
      </>
    );
}

export default GameZone;
0

There are 0 best solutions below