reactjs - 使用 useRef 进行 react ,将组件滚动到 View 中

标签 reactjs

我正在尝试让导航栏中的 onclick 处理程序将不同的组件滚动到 View 中。 我找到了一种可行的方法,但是我收到了来自 React 的警告,并且代码看起来不太干净。我希望有人知道如何以更正确的方式解决这个问题,以便警告消失并保持代码干净。

我将在每个组件上创建一个scrollTo,因此在 Header.js 中将会有几乎相似的调用,只是名称不同。

这是应用程序的结构:

App.js

const App = () => {
    return (
        <div>
            <Header />
            <Banner />
            <About />
            <Technology />
            <Contact />
            <Portfolio />
        </div>
    );
};

技术.js

const Technology = () => {
    return (
        <section className="technology">
            <div className="heading white">
                <h2>Technologies</h2>
                <p>Some techno</p>
            </div>
        </section>
    )
   }

Header.js(导航栏)

const Header = () => {
    let technology;

useEffect(() => {
        technology = document.querySelector(".technology");
    }, []);

    return (
        <header>
            <p className="logo">Portfolio</p>
            <div className="toggle"></div>
            <ul>
                <li>
                    <p onClick={() => window.scrollTo({ top: 0, behavior: "smooth" })}>
                        Home
                    </p>
                </li>
                <li>
                    <p>About Me</p>
                </li>
                <li>
                    <p onClick={() => technology.scrollIntoView({ behavior: "smooth" })}>
                        Technologies
                    </p>
                </li>
                <li>
                    <p>Contact</p>
                </li>
                <li>
                    <p>Projects</p>
                </li>
            </ul>
        </header>
    );
};

这是警告:

Assignments to the 'technology' variable from inside React Hook useEffect will be lost after each render. To preserve the value over time, store it in a useRef Hook and keep the mutable value in the '.current' property. Otherwise, you can move this variable directly inside useEffect

为了解决这个问题,我想我需要将它从 App.js 传递到 Header.js,并将其从每个组件获取到 App.js?不幸的是,我的谷歌搜索能力不足以解决这个问题。

我知道 React 有一个库可以解决这个问题,但我现在希望以更“原生”的方式解决这个问题。

最佳答案

您可以使用函数 refs 非常灵活地完成此操作,这将允许元素将自身注册到通用 ref 对象上。 Refs 绝对是最佳选择;使用 React 时,您希望尽可能避免直接访问 DOM。

const { useRef } = React;

function App() {
  const pageRefs = useRef({});

  return (
    <div className="app">
      <Header pageRefs={pageRefs} />
      <About pageRefs={pageRefs} />
      <Technology pageRefs={pageRefs} />
      <Portfolio pageRefs={pageRefs} />
    </div>
  );
};

function Header({ pageRefs }) {

  function scrollIntoView(type) {
    pageRefs.current[type].scrollIntoView({ behavior: "smooth" });
  };

  return (
    <header>
      <button onClick={() => scrollIntoView('about')}>
        About
      </button>
      <button onClick={() => scrollIntoView('techno')}>
        Technology
      </button>
      <button onClick={() => scrollIntoView('portfolio')}>
        Portfolio
      </button>
    </header>
  );
};

function About({ pageRefs }) {
  return (
    <section
      className="page about"
      ref={el => pageRefs.current = { ...pageRefs.current, about: el }}>
      About
    </section>
  );
};

function Technology({ pageRefs }) {
  return (
    <section
      className="page techno"
      ref={el => pageRefs.current = { ...pageRefs.current, techno: el }}>
      Technology
    </section>
  );
};

function Portfolio({ pageRefs }) {
  return (
    <section
      className="page portfolio"
      ref={el => pageRefs.current = { ...pageRefs.current, portfolio: el }}>
      Portfolio
    </section>
  );
};

ReactDOM.render(<App />, document.getElementById('root'));
* {
  padding: 0;
  margin: 0;
}

.app {
  width: 100%;
}

.page {
  width: 100%;
  height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
}

.about {
  background-color: crimson;
}

.techno {
  background-color: lemonchiffon;
}

.portfolio {
  background-color: cornflowerblue;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="root"></div>

关于reactjs - 使用 useRef 进行 react ,将组件滚动到 View 中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64188338/

相关文章:

javascript - React JS - 带有数据切换的链接不会重定向到 url

javascript - 在 ReactJS 中按列搜索

javascript - 如何在整个屏幕上插入背景图像?

javascript - React-Router 事件类不适用于嵌套路由

javascript - Reactjs 服务器端模板

javascript - ShallowWrapper 只能包装有效元素 - Enzyme Reactjs

reactjs - 如何区分React组件渲染的原因 : something from the inside or from the outside of the component?

reactjs - userData.name 未显示用户名

reactjs - 对于基于类的组件,useRouteMatch 的等价物是什么?

javascript - 动态更改引导表特定行的颜色