1

我对设置这个过于简单的页面的内容结构感到好奇。有一个导航/菜单栏,其中包含指向页面下方引用内容的锚点的链接。我不需要基于反应路由器的 URL 散列或历史跟踪。我不想在导航栏中进行 DOM 查询,但我看到的问题是我当前的设置将这些组件作为同级组件,因此ref为组件创建 's 意味着我必须创建一个 janky 中间处理程序以在 2 之间传递它们地方。

主应用

const App = () => {
  return (
    <Provider store={store}>
      <div className="app">
        <Navibar />
        <Jumbo />
        <About /> // should have a ref
        <Projects />  // should have a ref
        <Contact />  // should have a ref
      </div>
    </Provider>
  );
};

导航栏详细信息

handleClick = (e) => {
  window.scrollTo({
            top:this.myRef.current.offsetTop, 
            behavior: "smooth"
        })
}

<NavLink href="#about" onClick={this.handleClick}>About</NavLink>

在主应用程序级别,我不需要将其设为具有道具/状态的类,它应该只是一个功能组件。也许这就是我的逻辑有缺陷的地方?但是,如果我让 App 组件接受 refCallbacks 并将它们传递给 Navibar,那会解决它吗?

4

1 回答 1

5

<li>onClick中的函数有助于防止handleScrollTo()加载时触发

class App extends React.Component {
  refA = React.createRef()
  refB = React.createRef()
  
  componentDidMount() {
    this.setState({ loaded: true })
  }
  
  handleScrollTo = (elRef) => {
    // Incase the ref supplied isn't ref.current
    const el = elRef.current ? elRef.current : elRef
    
    // Scroll the element into view
    el.scrollIntoView({
      behavior: 'smooth',
      block: 'start'
    })
  }
  
  render() {
    return (
      <article>
        <header>
          <h1>ScrollTo Component</h1>
        </header>

        <nav>
          <ul>
            <li onClick={() => { this.handleScrollTo(this.refA) }}>
              Programs
            </li>
            <li onClick={() => { this.handleScrollTo(this.refB) }}>
              About
            </li>
          </ul>
        </nav>

        <div className="spacer"></div>

        <div ref={this.refA}>
          <h2>Programs</h2>
          <p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</p>
        </div>

        <div className="spacer"></div>

        <div ref={this.refB}>
          <h2>About</h2>
          <p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</p>
        </div>
      </article>
    )
  }
}

ReactDOM.render(<App />, document.getElementById('root'));
li {
  cursor: pointer;
}

.spacer {
  margin: 100px 0 100px 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>

于 2018-12-19T01:09:50.340 回答