简体   繁体   English

React Hooks - 滚动

[英]React Hooks - Scroll

Case Closed结案

Apparently l added a fixed div where the content laid so the only scrollable thing was that div not the window.显然我在内容放置的地方添加了一个固定的 div,所以唯一可滚动的是那个 div 而不是 window。 So handle scroll now is triggered successfully if i removed fixed from content div.因此,如果我从内容 div 中删除了固定,则现在可以成功触发句柄滚动。 Thanks谢谢

I have been using React in old way before React Hooks and l was able to create event listeners without any problem inside ComponentDidMount lifecycle hook and remove them safely in ComponentWillUnmount;在 React Hooks 之前,我一直在以旧方式使用 React,并且我能够在 ComponentDidMount 生命周期钩子中毫无问题地创建事件侦听器并在 ComponentWillUnmount 中安全地删除它们;

I tried the same inside useEffect Hook but apparently event listener ain't created and therefore handleScroll never called.我在 useEffect Hook 内部尝试了相同的方法,但显然没有创建事件侦听器,因此从未调用过 handleScroll。 Any idea on this?对此有任何想法吗?

import React, { useEffect, useState, useRef } from 'react';
import './Navbar.scss';

const Navbar = () => {

    const [scrollY, setScrollY] = useState(0);
    const Position = useRef(null);  

    useEffect(() => {
        window.addEventListener('scroll', handleScroll);
    }, []);

    const handleScroll = () => {
        console.log(Position);
    }

    return (
        <div className="row">
            <div className="col-lg-12 p-0">
                <div className="Navbar" ref={Position}>
                    <ul>
                        <li><a href="/us">KDN</a></li>
                        <li><a href="/">Posts</a></li>
                        <li><a href="/">Talk </a></li>
                        <li><a href="/jobs">Jobs</a></li>
                    </ul>
                </div>
            </div>
        </div>
    );
};

export default Navbar;

An issue here is the scope that the initial addEventListener is working on.这里的一个问题是初始 addEventListener 正在处理的 scope。 In regular JS you would always have the current value in the scope, however, in hooks, your code will reference stale values from previous renders.在常规 JS 中,您始终会在 scope 中拥有当前值,但是,在挂钩中,您的代码将引用以前渲染中的陈旧值。 In your case, you are having the Position in initial state (null).在您的情况下,您在初始 state(空)中拥有 Position。 What you need to do is actually to remove the dependency argument so that the event is being added on each render of the component or add a dependency on Position.current variable.您需要做的实际上是删除依赖项参数,以便在组件的每个渲染上添加事件或添加对 Position.current 变量的依赖项。 So what you want is this:所以你想要的是这样的:

useEffect(() => {
    window.addEventListener('scroll', handleScroll);

    return () => {
        window.removeEventListened('scroll', handleScroll);
    }
}, [Position.current]);

Plus in your handleScroll function you most likely want to console.log(Position.current)加上你的 handleScroll function 你最有可能想要console.log(Position.current)

Inorder for the event to be triggered, you need to render elements whose height is more than the viewport height.为了触发事件,您需要渲染高度大于视口高度的元素。 And for removing event listner using useEffect you have to return a function which will be triggered on unmount对于使用useEffect删除事件侦听器,您必须返回一个 function 将在卸载时触发

for example例如

useEffect(() => {
  window.addEventListener("scroll", handleScroll);
  return () => {
  window.removeEventListener("scroll", handleScroll);
  };
}, []);

for further reference on useEffect hook please refer rect documentation有关useEffect挂钩的进一步参考,请参阅rect 文档

try this code试试这个代码

<div className="row">
  <div className="col-lg-12 p-0">
    <div className="Navbar" ref={Position} style={{ minHeight: "150vh" }}>
      <ul>
        <li>
          <a href="/us">KDN</a>
        </li>
        <li>
          <a href="/">Posts</a>
        </li>
        <li>
          <a href="/">Talk </a>
        </li>
        <li>
          <a href="/jobs">Jobs</a>
        </li>
      </ul>
    </div>
  </div>
</div>

you can also see the working demo in this sandbox您还可以在沙箱中查看工作演示

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM