首页 > 解决方案 > 与子组件的交叉观察者反应

问题描述

我正在尝试使用交叉点观察器实现无限滚动,我有一个在子组件中呈现的数据列表。

所以我在渲染时将目标元素附加到列表元素的最后一个。

问题是在 2 api 调用之后它没有触发,因为我在 App.js 函数 handleObserver 中有一个条件

如果(this.state.prevY > y){

所以在第二个 api 调用它没有发生之后,条件是错误的。所以很明显api调用再也不会发生了。

prevY 越来越大。

我该如何解决这个问题,每篇文章都显示在父级组件中。我正在尝试使用子组件来实现。

任何帮助表示赞赏

App.js

import React, { Component } from 'react';
import Child from './Child';
import axios from 'axios';

class App extends Component {
  state = {
    users: [],
    page: 0,
    loading: false,
    prevY: 0,
    isDataAvailable: false
  };

  componentDidMount(){
    this.getUsers(this.state.page)
  }


  getUsers = (page = this.state.page) => {
    this.setState({ loading: true });
    axios
      .get(`https://api.github.com/users?since=${page}&per_page=100`)
      .then(res => {
        this.setState({ users: [...this.state.users, ...res.data] });
        this.setState({ loading: false, isDataAvailable: true });
      });
  }

  handleObserver = (entities, observer) => {
    const y = entities[0].boundingClientRect.y;
    if (this.state.prevY > y) {
      const lastUser = this.state.users[this.state.users.length - 1];
      const curPage = lastUser.id;
      this.getUsers(curPage);
      this.setState({ page: curPage });
    }
    this.setState({ prevY: y });
  }

  render() {
    return (
      <div className="container">
        <div style={{ minHeight: '800px' }}>
          {this.state.isDataAvailable ? (
            <Child
              handleObserver={this.handleObserver}
              users={this.state.users}
            />
          ) : null}
         
        </div>
      </div>
    );
  }
}

export default App;



// Child.js
import React, { Component } from 'react';

class Child extends Component {
  componentDidMount() {
    const options = {
      root: null,
      threshold: 0,
    };
    this.observer = new IntersectionObserver(
      this._handleObserver.bind(this),
      options,
    );
    this.observer.observe(this.loadingRef);
  }

  shouldComponentUpdate(nextProps) {
    return this.props.users !== nextProps.users;
  }

  _handleObserver(entities, observer) {
    this.props.handleObserver(entities)
  }

  render() {
    return (
      <ul>
        {this.props.users.map(
          (user, index) =>
            (index ===
              this.props.users.length - 1 ? (
                <div>
                  <div ref={loadingRef => (this.loadingRef = loadingRef)} />
                  <li key={user.id}>{user.login}</li>
                </div>
              ) : (
                <li key={user.id}>{user.login}</li>
              )),
        )}
      </ul>
    );
  }
}

export default Child;

标签: javascriptreactjs

解决方案


所以问题是每次loadingRef都在变化,所以我们每次都需要指出ref。

componentDidUpdate(){
 this.observer.observe(this.loadingRef)
}

最初,loadingRef 将指向第 99 个元素,稍后它将指向第 199 个元素。所以我们需要更新loadingRef的指向。

通过在子组件中添加上述代码,我能够解决问题。


推荐阅读