如何使组件在React.js中滚动显示/隐藏

如何使组件在React.js中滚动显示/隐藏

问题描述:

我试图仅在用户向下滚动到页眉上方时显示页脚横幅,并在用户向上滚动至顶部时隐藏页脚横幅.我如何实现此目标的想法是在页面的顶部组件中为滚动事件添加一个事件侦听器.这是我当前的代码.但这不起作用:

I'm trying to make a footer banner show only when user scrolls down past the header, and hide it when user scrolls up to top. My idea of how to implement this is to add an event listener for scroll event in the top component of the page. Here's my current code. But it doesn't work:

componentDidMount() {
  this.nv.addEventListener('scroll', this.handleScroll);
}

handleScroll(e) {
  if(window.pageYOffset > 50 && window.pageYOffset < 900) {
    console.log('scrolled');
    this.setState({
      showBanner: true,
    });
  } else {
    this.setState({
      showBanner: false,
    });
  }
}

顶部组件的渲染方法:

render() {
  return (
    <div ref={elem => this.nv = elem}>
      <Header/>
      <Body
        userInfo={this.props.userInfo}
        history={this.props.history}
      />
      {
        this.state.showBanner && <Banner/>
        || null
      }
    </div>
  )
}

我看不到任何日志,滚动时显然未调用 setState .

I don't see any logs and the setState is apparently not called when scrolling.

关于如何实现预期目标的任何建议?

Any suggestion on how I can accomplish the intended goal?

*更新* 更改了 componentDidMount 以在窗口上添加事件侦听器,现在可以正常工作了.

* UPDATE * Changed componentDidMount to add event listener on window, now it's working.

componentDidMount() {
  window.addEventListener('scroll', this.handleScroll);
}

原因是因为您试图将事件侦听器添加到尚不存在的引用中. componentDidMount 发生在初始渲染之前.这意味着尚未设置您在渲染器中分配的引用.

The reason is because you are trying to add an event listener to a ref that doesn't exist yet. componentDidMount happens BEFORE the initial render. That means that the ref you assign in render hasn't been set yet.

您可以使用ref回调并将事件侦听器附加到那里:

You can use a ref callback and attach the event listener there:

applyRef = ref => {
  this.vn = ref;
  this.vn.addEventListener('scroll', this.handleScroll);
}
render() {
  return (
    <div ref={this.applyRef}>
      <Header/>
      <Body
        userInfo={this.props.userInfo}
        history={this.props.history}
      />
      {
        this.state.showBanner && <Banner/>
        || null
      }
    </div>
  )
}