Javascript 滚动回顶部按钮在React.js中不起作用

Javascript 滚动回顶部按钮在React.js中不起作用,javascript,reactjs,Javascript,Reactjs,我正在进行一个基于React的项目,并尝试在页脚中实现一个按钮,用于单击滚动顶部,但面临一个我还无法解决的问题。如果你想看到代码,请点击下面的链接 // GoTop.js import React from 'react'; const GoTopd = (props) => { const [intervalId, setIntervalId] = React.useState(0); const [thePosition, setThePosition] = Re

我正在进行一个基于React的项目,并尝试在页脚中实现一个按钮,用于单击滚动顶部,但面临一个我还无法解决的问题。如果你想看到代码,请点击下面的链接

// GoTop.js

import React from 'react';

const GoTopd = (props) => {

    const [intervalId, setIntervalId] = React.useState(0);
    const [thePosition, setThePosition] = React.useState(false);

    React.useEffect(() => {
        document.addEventListener("scroll", () => {
            if (window.scrollY > 170) {
                setThePosition(true)
            } else {
                setThePosition(false);
            }
        });
        // window.scrollTo(0, 0);
    }, [])

    const onScrollStep = () => {
        if (window.pageYOffset === 0){
            clearInterval(intervalId);
        }
        window.scroll(0, window.pageYOffset - props.scrollStepInPx);
    }

    const scrollToTop = () => {
        const intervalId = setInterval(onScrollStep, props.delayInMs);
        setIntervalId(intervalId);
    }

    const renderGoTopIcon = () => {
        return (
            <div className={`go-top ${thePosition ? 'active' : ''}`} onClick={scrollToTop}>
                <i className="arrow alternate circle up outline icon"></i>
            </div>
        )
    }

    return (
        <React.Fragment>
            {renderGoTopIcon()}
        </React.Fragment>
    )
}

export default GoTopd;
这段代码的问题是,当第一次加载并转到该页面的下方时,它工作正常,但之后,我无法转到需要再次刷新的页面。我不明白为什么会有这样的行为

谁能找出问题所在吗

谢谢你的帮助


感谢使用React,您可以使用非常简单的解决方案滚动到顶部,但我将展示如何改进代码。您可以使用refs。 请注意,clearInterval中的
inrevaltId
为0,不引用间隔,因此无法清除间隔

const timeoutRef = React.useRef(null);

const onScrollStep = () => {

  if (window.pageYOffset === 0){
     clearInterval(timeoutRef.current);
  }
  window.scroll(0, window.pageYOffset - props.scrollStepInPx);
}

const scrollToTop = () => {
  timeoutRef.current = setInterval(onScrollStep, props.delayInMs);
}

Fiddle示例:

使用React,您可以使用非常简单的解决方案滚动到顶部,但我将展示如何改进代码。您可以使用refs。 请注意,clearInterval中的
inrevaltId
为0,不引用间隔,因此无法清除间隔

const timeoutRef = React.useRef(null);

const onScrollStep = () => {

  if (window.pageYOffset === 0){
     clearInterval(timeoutRef.current);
  }
  window.scroll(0, window.pageYOffset - props.scrollStepInPx);
}

const scrollToTop = () => {
  timeoutRef.current = setInterval(onScrollStep, props.delayInMs);
}

小提琴示例:

这里是
setInterval

const{
useRef,
useState,
使用效果
}=反应;
常量应用=()=>{
const ref=useRef(null);
const[isBottom,setBottom]=useState(false);
useffect(()=>{
}, [])
useffect(()=>{
常量元素=ref&&ref.current;
if(元素){
const checkIsBottomOfPage=()=>{
如果(window.scrollY>=window.innerHeight){
setBottom(真)
}否则{
setBottom(假);
}
}
文档。添加了文本列表(“滚动”,选中页面底部);
window.scrollTo({
顶部:element.scrollHeight
})
检查页面底部();
return()=>{
返回文档。删除EventListener(“滚动”,选中页面底部);
}
}
},[ref])
const onScroll=(顶部)=>{
常数incOrDec=顶部1:-1;
让chunk=-1;
让位置=window.scrollY;
让isScrollComplete=null;
如果(顶部===0){
chunk=-ref.current.scrollHeight/3;
isScrollComplete=()=>window.scrollY<10;
}
否则{
chunk=top/3;
isScrollComplete=()=>window.scrollY>=window.innerHeight
}
常量滚动步骤=()=>{
位置=位置+区块;
window.scrollTo({
行为:“平滑”,
顶部:位置
})
如果(IsCrollComplete()){
返回;
}
设置超时(滚动步骤,300);
}
设置超时(滚动步骤,300)
}
const onscrollbooth=()=>onScroll(ref.current.scrollHeight);
const onScrollTop=()=>onScroll(0);
返回
<
按钮样式={
{
填充:'.5rem'
}
}
onClick={
浅滩
}>滚动到底部<
div样式={
{
背景:“灰色”,
高度:“200vh”
}
}>
< 按钮样式={ { 可见性:isBottom?'visible':'hidden', 填充:'.5rem' } } onClick={ 在Crolltop上 }>滚动至顶部< /div> } ReactDOM.render(< App/>, document.getElementById('root')) );
这里是
setInterval

const{
useRef,
useState,
使用效果
}=反应;
常量应用=()=>{
const ref=useRef(null);
const[isBottom,setBottom]=useState(false);
useffect(()=>{
}, [])
useffect(()=>{
常量元素=ref&&ref.current;
if(元素){
const checkIsBottomOfPage=()=>{
如果(window.scrollY>=window.innerHeight){
setBottom(真)
}否则{
setBottom(假);
}
}
文档。添加了文本列表(“滚动”,选中页面底部);
window.scrollTo({
顶部:element.scrollHeight
})
检查页面底部();
return()=>{
返回文档。删除EventListener(“滚动”,选中页面底部);
}
}
},[ref])
const onScroll=(顶部)=>{
常数incOrDec=顶部1:-1;
让chunk=-1;
让位置=window.scrollY;
让isScrollComplete=null;
如果(顶部===0){
chunk=-ref.current.scrollHeight/3;
isScrollComplete=()=>window.scrollY<10;
}
否则{
chunk=top/3;
isScrollComplete=()=>window.scrollY>=window.innerHeight
}
常量滚动步骤=()=>{
位置=位置+区块;
window.scrollTo({
行为:“平滑”,
顶部:位置
})
如果(IsCrollComplete()){
返回;
}
设置超时(滚动步骤,300);
}
设置超时(滚动步骤,300)
}
const onscrollbooth=()=>onScroll(ref.current.scrollHeight);
const onScrollTop=()=>onScroll(0);
返回
<
按钮样式={
{
填充:'.5rem'
}
}
onClick={
浅滩
}>滚动到底部<
div样式={
{
背景:“灰色”,
高度:“200vh”
}
}>
< 按钮样式={ { 可见性:isBottom?'visible':'hidden', 填充:'.5rem' } } onClick={ 在Crolltop上 }>滚动至顶部< /div> } ReactDOM.render(< App/>, document.getElementById('root')) );
使用React钩子滚动到顶部的简单解决方案

.App {
  text-align: center;
  height: 5000px;
}

.scrollTop {
  position: fixed; 
  width: 100%;
  bottom: 20px;
  align-items: center;
  height: 20px;
  justify-content: center;
  z-index: 1000;
  cursor: pointer;
  animation: fadeIn 0.3s;
  transition: opacity 0.4s;
  opacity: 0.5;
}

.scrollTop:hover{
  opacity: 1;
}

@keyframes fadeIn {
  0% {
    opacity: 0;
  }
  100% {
    opacity: 0.5;
  }
}
ScrollTopArrow.tsx

import React, { FC, useState, useEffect } from 'react'
import {FaArrowCircleUp} from 'react-icons/fa';
import '../App.css';
type ScrollTopArrowProps = {
    showBelow?: number
}
const ScrollTopArrow: FC<ScrollTopArrowProps> = ({ showBelow = 400 }) => {
    const [showScroll, setShowScroll] = useState<boolean>(false)
    useEffect(() => {
        window.addEventListener('scroll', checkScrollTop)
        return () => {
            window.removeEventListener('scroll', checkScrollTop)
        }
    })
    const checkScrollTop = () => {
        if (!showScroll && window.pageYOffset > showBelow) {
            setShowScroll(true)
        } else if (showScroll && window.pageYOffset <= showBelow) {
            setShowScroll(false)
        }
    }

    const scrollTop = () => {
        window.scrollTo({ top: 0, behavior: 'smooth' })
    }
    return (
        <FaArrowCircleUp className="scrollTop" onClick={scrollTop} style={{height: 40, display: showScroll ? 'flex' : 'none'}}/>
    )
}

export { ScrollTopArrow }
import React from 'react'
import './App.css'
import {ScrollTopArrow} from './components/ScrollTopArrow'

function App() {
  return (
    <div className="App">
      <ScrollTopArrow/>
    </div>
  );
}

export default App
App.tsx

import React, { FC, useState, useEffect } from 'react'
import {FaArrowCircleUp} from 'react-icons/fa';
import '../App.css';
type ScrollTopArrowProps = {
    showBelow?: number
}
const ScrollTopArrow: FC<ScrollTopArrowProps> = ({ showBelow = 400 }) => {
    const [showScroll, setShowScroll] = useState<boolean>(false)
    useEffect(() => {
        window.addEventListener('scroll', checkScrollTop)
        return () => {
            window.removeEventListener('scroll', checkScrollTop)
        }
    })
    const checkScrollTop = () => {
        if (!showScroll && window.pageYOffset > showBelow) {
            setShowScroll(true)
        } else if (showScroll && window.pageYOffset <= showBelow) {
            setShowScroll(false)
        }
    }

    const scrollTop = () => {
        window.scrollTo({ top: 0, behavior: 'smooth' })
    }
    return (
        <FaArrowCircleUp className="scrollTop" onClick={scrollTop} style={{height: 40, display: showScroll ? 'flex' : 'none'}}/>
    )
}

export { ScrollTopArrow }
import React from 'react'
import './App.css'
import {ScrollTopArrow} from './components/ScrollTopArrow'

function App() {
  return (
    <div className="App">
      <ScrollTopArrow/>
    </div>
  );
}

export default App
从“React”导入React
导入“./App.css”
从“./components/ScrollTopArrow”导入{ScrollTopArrow}
函数App(){
返回(
);
}
导出默认应用程序

使用React钩子滚动到顶部的简单解决方案

.App {
  text-align: center;
  height: 5000px;
}

.scrollTop {
  position: fixed; 
  width: 100%;
  bottom: 20px;
  align-items: center;
  height: 20px;
  justify-content: center;
  z-index: 1000;
  cursor: pointer;
  animation: fadeIn 0.3s;
  transition: opacity 0.4s;
  opacity: 0.5;
}

.scrollTop:hover{
  opacity: 1;
}

@keyframes fadeIn {
  0% {
    opacity: 0;
  }
  100% {
    opacity: 0.5;
  }
}
ScrollTopArrow.tsx

import React, { FC, useState, useEffect } from 'react'
import {FaArrowCircleUp} from 'react-icons/fa';
import '../App.css';
type ScrollTopArrowProps = {
    showBelow?: number
}
const ScrollTopArrow: FC<ScrollTopArrowProps> = ({ showBelow = 400 }) => {
    const [showScroll, setShowScroll] = useState<boolean>(false)
    useEffect(() => {
        window.addEventListener('scroll', checkScrollTop)
        return () => {
            window.removeEventListener('scroll', checkScrollTop)
        }
    })
    const checkScrollTop = () => {
        if (!showScroll && window.pageYOffset > showBelow) {
            setShowScroll(true)
        } else if (showScroll && window.pageYOffset <= showBelow) {
            setShowScroll(false)
        }
    }

    const scrollTop = () => {
        window.scrollTo({ top: 0, behavior: 'smooth' })
    }
    return (
        <FaArrowCircleUp className="scrollTop" onClick={scrollTop} style={{height: 40, display: showScroll ? 'flex' : 'none'}}/>
    )
}

export { ScrollTopArrow }
import React from 'react'
import './App.css'
import {ScrollTopArrow} from './components/ScrollTopArrow'

function App() {
  return (
    <div className="App">
      <ScrollTopArrow/>
    </div>
  );
}

export default App
Ap