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.
我有一个问题,我正在使用Reaction,我有一个导航栏组件,一个主页,在主页内我有另一个组件是项目,我在导航栏中有一个按钮,当我按下它时,我想滚动IntoView到项目组件中的div。我在子组件中使用ForwardRef来使其工作。
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
当我在主页(/home)时,它工作得很好,但如果我从其他路径渲染的另一个组件按下它,(/Gamezone)我想要做的行为是,首先导航到主页路径,然后滚动Into查看项目,但这里没有定义ref。我知道我只是将孩子的引用转发到主页,但我不知道如何让它自己实现,这样我就可以引用引用,而不是在调用游戏空间中的函数时将其设置为未定义
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
我尝试在上下文中生成Ref以将其提供给所有路由,我还尝试了flushSync以使DOM重新加载,也许当我导航到/home路径时,Ref会自动实现,但我无法使其工作
Here is the resumed code:
下面是恢复的代码:
App.js
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;
更多回答
In this case I would break the React pattern - append an hash to the url with the id of the element you want to scroll to, read it inside a useEffect and document.querySelector
it - no ref madness!
在这种情况下,我会打破React模式-将一个hash附加到你想要滚动到的元素的id的url中,在useEffect和document中读取它。
I solved it passing a state in the useNavigate() and in the homepage component in the useEffect i check against that state and scrollIntoView to the ref declared :) Thanks!
我解决了这个问题,在useNavigate()中传递了一个状态,并在useEffect中的主页组件中检查了该状态,并滚动IntoView到ref声明:)谢谢!
我是一名优秀的程序员,十分优秀!