Javascript 反应如何等待组件/页面呈现以调用函数
我需要修改我在这里返回的第一个div的data scroll属性。问题似乎是种族危险-active为空,因为dom尚未加载。我该怎么处理?异步/等待?我不是在质疑什么,也不会得到回应。如何等待直到呈现标头 这将生成TypeError:无法读取null的属性“dataset”:Javascript 反应如何等待组件/页面呈现以调用函数,javascript,reactjs,Javascript,Reactjs,我需要修改我在这里返回的第一个div的data scroll属性。问题似乎是种族危险-active为空,因为dom尚未加载。我该怎么处理?异步/等待?我不是在质疑什么,也不会得到回应。如何等待直到呈现标头 这将生成TypeError:无法读取null的属性“dataset”: import { Link } from 'react-router-dom'; import * as ROUTES from '../constants/routes'; export default functio
import { Link } from 'react-router-dom';
import * as ROUTES from '../constants/routes';
export default function Header() {
const active = document.getElementById('navbar');
const debounce = (fn) => {
let frame;
return (...params) => {
if (frame) {
cancelAnimationFrame(frame);
}
frame = requestAnimationFrame(() => {
fn(...params);
});
};
};
const storeScroll = () => {
if (window.scrollY > 80) {
active.dataset.scroll = window.scrollY;
}
if (window.scrollY <= 80) {
active.dataset.scroll = 0;
}
};
// Listen for new scroll events
document.addEventListener('scroll', debounce(storeScroll), { passive: true });
// Update scroll position for first time
storeScroll();
return (
<div id="navbar" data-scroll="0">
<header className="fixed flex top-0 scroll:bg-blue-500 bg-transparent items-center justify-center p-5 w-full">
<div className="container mx-auto max-w-screen-lg h-full">
<div className="flex justify-between h-full">
<div className="text-black text-center flex items-center align-items cursor-pointer">
<h1 className="flex justify-center w-full">
<Link to={ROUTES.TEST} className="font-bold text-lg" aria-label="home">
HOME
</Link>
</h1>
</div>
</div>
</div>
</header>
</div>
);
}
从'react router dom'导入{Link};
从“../constants/ROUTES”导入*作为路由;
导出默认函数头(){
const active=document.getElementById('navbar');
常数去盎司=(fn)=>{
让框架;
返回(…参数)=>{
如果(帧){
取消动画帧(帧);
}
frame=requestAnimationFrame(()=>{
fn(…参数);
});
};
};
const storeScroll=()=>{
如果(window.scrollY>80){
active.dataset.scroll=window.scrollY;
}
如果(window.scrollY您可以使用useffect
挂钩:
import { useEffect } from 'react';
useEffect(()=>{
// what should happen after the initial render
const active = document.getElementById('navbar');
active.setAttribute("data-scroll", <your_value>)
},[]);
从“react”导入{useffect};
useffect(()=>{
//在初始渲染之后应该发生什么
const active=document.getElementById('navbar');
active.setAttribute(“数据滚动”,)
},[]);
您需要使用ref
来“捕获”DOM元素
const debounce=(fn)=>{
让框架;
返回(…参数)=>{
如果(帧){
取消动画帧(帧);
}
frame=requestAnimationFrame(()=>{
fn(…参数);
});
};
};
常量storeScroll=(元素)=>()=>{
如果(window.scrollY>80){
active.dataset.scroll=window.scrollY;
}
如果(window.scrollY{
如果(!元素){
返回null;
}
addEventListener('scroll',debounce(storeScroll(element)),{passive:true});
storeScroll(元素);
}
返回(
...
);
}
尽管可以使用document.getElementById
,但React中不鼓励使用它,而获取DOM元素引用的惯用方法是通过引用
从组件中拉出函数并不是绝对必要的,只是我推荐的一种做法
看
仅绑定useEffect中的事件
同样,您可以在useffect中访问导航栏
useEffect(() => {
const active = document.getElementById('navbar');
}, [])
在react中直接以底层DOM为目标不是一个好的做法。我们可以使用ref
来实现这一点
另外,您正在添加一个eventListener
,当组件卸载时,它不会被正确删除。因此,为了确保在渲染完成时拥有该元素,您可以使用useffect
钩子,该钩子保证在绘制DOM之后运行它
因此,您需要将eventListener代码移动到useEffect挂钩中。下面是使用Ref
和useEffect
更新的代码
import {Link} from 'react-router-dom';
import * as ROUTES from '../constants/routes';
import {useRef, useEffect} from 'react';
export default function Header() {
const navbarRef = useRef();
const debounce = (fn) => {
let frame;
return (...params) => {
if (frame) {
cancelAnimationFrame(frame);
}
frame = requestAnimationFrame(() => {
fn(...params);
});
};
};
const storeScroll = () => {
if (window.scrollY > 80) {
navbarRef.current.dataset.scroll = window.scrollY;
}
if (window.scrollY <= 80) {
navbarRef.current.dataset.scroll = 0;
}
};
useEffect(() => {
// Update scroll position for first time
storeScroll();
// attact the event listener
window.addEventListener('scroll', debounce(storeScroll), {passive: true});
// remove the event listener when the component is unmounted
return () =>
window.removeEventListener('scroll', debounce(storeScroll), {
passive: true,
});
}, []);
return (
<div id="navbar" ref={navbarRef} data-scroll="0">
<header className="fixed flex top-0 scroll:bg-blue-500 bg-transparent items-center justify-center p-5 w-full">
<div className="container mx-auto max-w-screen-lg h-full">
<div className="flex justify-between h-full">
<div className="text-black text-center flex items-center align-items cursor-pointer">
<h1 className="flex justify-center w-full">
<Link
to={ROUTES.TEST}
className="font-bold text-lg"
aria-label="home"
>
HOME
</Link>
</h1>
</div>
</div>
</div>
</header>
</div>
);
}
从'react router dom'导入{Link};
从“../constants/ROUTES”导入*作为路由;
从“react”导入{useRef,useffect};
导出默认函数头(){
const navbarRef=useRef();
常数去盎司=(fn)=>{
让框架;
返回(…参数)=>{
如果(帧){
取消动画帧(帧);
}
frame=requestAnimationFrame(()=>{
fn(…参数);
});
};
};
const storeScroll=()=>{
如果(window.scrollY>80){
navbarRef.current.dataset.scroll=window.scrollY;
}
如果(window.scrollY{
//第一次更新滚动位置
storeScroll();
//附加事件侦听器
addEventListener('scroll',debounce(storeScroll),{passive:true});
//卸载组件时删除事件侦听器
return()=>
window.removeEventListener('scroll',debounce(storeScroll){
被动:是的,
});
}, []);
返回(
家
);
}
import {Link} from 'react-router-dom';
import * as ROUTES from '../constants/routes';
import {useRef, useEffect} from 'react';
export default function Header() {
const navbarRef = useRef();
const debounce = (fn) => {
let frame;
return (...params) => {
if (frame) {
cancelAnimationFrame(frame);
}
frame = requestAnimationFrame(() => {
fn(...params);
});
};
};
const storeScroll = () => {
if (window.scrollY > 80) {
navbarRef.current.dataset.scroll = window.scrollY;
}
if (window.scrollY <= 80) {
navbarRef.current.dataset.scroll = 0;
}
};
useEffect(() => {
// Update scroll position for first time
storeScroll();
// attact the event listener
window.addEventListener('scroll', debounce(storeScroll), {passive: true});
// remove the event listener when the component is unmounted
return () =>
window.removeEventListener('scroll', debounce(storeScroll), {
passive: true,
});
}, []);
return (
<div id="navbar" ref={navbarRef} data-scroll="0">
<header className="fixed flex top-0 scroll:bg-blue-500 bg-transparent items-center justify-center p-5 w-full">
<div className="container mx-auto max-w-screen-lg h-full">
<div className="flex justify-between h-full">
<div className="text-black text-center flex items-center align-items cursor-pointer">
<h1 className="flex justify-center w-full">
<Link
to={ROUTES.TEST}
className="font-bold text-lg"
aria-label="home"
>
HOME
</Link>
</h1>
</div>
</div>
</div>
</header>
</div>
);
}