首页 > 解决方案 > 将类组件转换为函数组件 - 根据滚动位置展开/折叠标题

问题描述

我的目标是将这个类组件变成一个函数组件。

然而,我的功能组件实现的问题是,当我向上滚动时,标题会立即展开。如果页面位于绝对顶部,我只希望标题可见。

import React, { useState, useEffect } from "react";
import classnames from "classnames";

import "./header.styles.scss";

const Header = () => {
  const [isHidden, setIsHidden] = useState(0);

  const [prevScrollPos, setPrevScollPos] = useState(window.pageYOffset);

  useEffect(() => {
    function handleScrollChange() {
      setIsHidden(prevScrollPos < window.pageYOffset);
      setPrevScollPos(window.pageYOffset);
    }
    window.addEventListener("scroll", handleScrollChange);
    return () => {
      window.removeEventListener("scroll", handleScrollChange);
    };
  });

  return (
    <div
      className={classnames("header", {
        "header-hidden": isHidden,
      })}
    >
      <div className="logo-container">A & A Solutions</div>
      <div className="options">
        <div className="option">Option 1</div>
        <div className="option">Option 2</div>
        <div className="option">Option 3</div>
      </div>
    </div>
  );
};

export default Header;

标签: javascriptcssreactjs

解决方案


您可以检查该window.scrollY属性并查看它是否为 0。这意味着窗口滚动条的 Y 轴顶部位于最顶部。

function handleScrollChange() {
  setIsHidden(window.scrollY !== 0);
}

作为旁注,我认为您不应该在每次发生副作用时添加和清理事件侦听器。您可能会考虑使用[]依赖项,useEffect因为您可以省略检查prevScrollPos

如果你想运行一个效果并且只清理一次(在挂载和卸载时),你可以传递一个空数组([])作为第二个参数。这告诉 React 你的效果不依赖于任何来自 props 或 state 的值,所以它永远不需要重新运行。


推荐阅读