Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 反应钩子滚动到元素_Javascript_Html_Reactjs_React Hooks - Fatal编程技术网

Javascript 反应钩子滚动到元素

Javascript 反应钩子滚动到元素,javascript,html,reactjs,react-hooks,Javascript,Html,Reactjs,React Hooks,我希望用React 16.8.6编写一个React钩子,在单击导航项时,可以滚动到特定的HTML元素部分。我有一个导航组件,它是页面上呈现的部分的同级 另外,当页面滚动时,我想用HTML部分更新应用程序的状态 导航组件JSX 如果您不介意使用react router dom,那么您可以跟踪历史记录更改,并通过哈希历史记录更改将滚动位置更新为HTML元素的id。这种方法的优点是您不必使用状态,也不必使用引用,而且它可以在整个应用程序中扩展(无论元素位于应用程序树中的何处,您都可以滚动到它们) 工作

我希望用React 16.8.6编写一个React钩子,在单击导航项时,可以滚动到特定的HTML元素部分。我有一个
导航
组件,它是页面上呈现的部分的同级

另外,当页面滚动时,我想用HTML部分更新
应用程序的状态

导航组件JSX
如果您不介意使用
react router dom
,那么您可以跟踪历史记录更改,并通过
哈希
历史记录更改将滚动位置更新为HTML元素的
id
。这种方法的优点是您不必使用状态,也不必使用引用,而且它可以在整个应用程序中扩展(无论元素位于应用程序树中的何处,您都可以滚动到它们)

工作示例

(演示)

(源代码——不幸的是,在codesandbox编辑器中不起作用)


组件/ScrollHandler(侦听哈希历史更改的钩子,搜索与哈希中的id匹配的元素,如果找到匹配的元素id,则滚动到该元素)

组件/导航(更改url哈希历史位置的链接)

index.js

import React from "react";
import { render } from "react-dom";
import { BrowserRouter } from "react-router-dom";

import Container from "./components/Container";
import Navigation from "./components/Navigation";
import Sections from "./components/Sections";
import ScrollHandler from "./components/ScrollHandler";
import "./styles.css";

const App = () => (
  <BrowserRouter>
    <Container>
      <ScrollHandler />
      <Navigation />
      <Sections />
    </Container>
  </BrowserRouter>
);

render(<App />, document.getElementById("root"));
从“React”导入React;
从“react dom”导入{render};
从“react router dom”导入{BrowserRouter};
从“/components/Container”导入容器;
从“/components/Navigation”导入导航;
从“/components/Sections”导入节;
从“/components/ScrollHandler”导入ScrollHandler;
导入“/styles.css”;
常量应用=()=>(
);
render(,document.getElementById(“根”));

您的导航和部分是否保存在同一个组件文件中?更新的说明。。。该组件与这些部分是分开的,但它们在单个页面上呈现。
<section className="section-1">Section 1</section>
<section className="section-2">Section 2</section>

const [navItem, setNavItem] = React.useState(null);
const sectionRef = React.useRef(null);

// Scroll To Item
useEffect(() => {
    console.log(sectionRef.current);
    if (sectionRef.current) {
      sectionRef.current.scrollToItem();
    }
}, []);
import { useEffect } from "react";
import PropTypes from "prop-types";
import { withRouter } from "react-router-dom";

const ScrollHandler = ({ location }) => {
  useEffect(() => {
    const element = document.getElementById(location.hash));

    setTimeout(() => {
      window.scrollTo({
        behavior: element ? "smooth" : "auto",
        top: element ? element.offsetTop : 0
      });
    }, 100);
  }, [location]);

  return null;
};

ScrollHandler.propTypes = {
  location: PropTypes.shape({
    pathname: PropTypes.string,
    search: PropTypes.string,
    hash: PropTypes.string,
    state: PropTypes.any,
    key: PropTypes.string
  }).isRequired
};

export default withRouter(ScrollHandler);
import React from "react";
import { Link } from "react-router-dom";
import List from "../List";

const Navigation = () => (
  <List>
    {[1, 2, 3, 4, 5].map(num => (
      <li key={num}>
        <Link to={`/#section${num}`}>Section {num}</Link>
      </li>
    ))}
  </List>
);

export default Navigation;
import React from "react";
import Headline from "../Headline";

const Sections = () =>
  [1, 2, 3, 4, 5].map(num => (
    <Headline key={num} id={`#section${num}`}>
      Section {num}
    </Headline>
  ));

export default Sections;
import React from "react";
import { render } from "react-dom";
import { BrowserRouter } from "react-router-dom";

import Container from "./components/Container";
import Navigation from "./components/Navigation";
import Sections from "./components/Sections";
import ScrollHandler from "./components/ScrollHandler";
import "./styles.css";

const App = () => (
  <BrowserRouter>
    <Container>
      <ScrollHandler />
      <Navigation />
      <Sections />
    </Container>
  </BrowserRouter>
);

render(<App />, document.getElementById("root"));