简体   繁体   English

使用无限滚动进行滚动高度调整

[英]Scroll height adjustment with infinity scroll

At the moment when 'scroll' is at the very bottom, the function getUsers () is called.在“滚动”位于最底部的那一刻,调用函数getUsers () How to set the scroll so that it doesn't reach the end of the slider, and the getUsers () function is called.如何设置滚动使其不会到达滑块的末尾,并调用getUsers ()函数。 That there would be an infinity scroll effect.会有无限滚动效果。 I mean the scroll effect like here: https://codesandbox.io/s/ww7npwxokk .我的意思是像这里的滚动效果: https : //codesandbox.io/s/ww7npwxokk When the scroll reaches the bottom, it goes back.当滚动到达底部时,它返回。

Code here: https://stackblitz.com/edit/react-nq8btq代码在这里: https : //stackblitz.com/edit/react-nq8btq

import './style.css';
import axios from 'axios';

class App extends Component {
  constructor() {
    super();
    this.state = {
      users: [],
      page: 1
    };
  }

  componentDidMount() {
    this.getUsers();
  }

  getUsers = () => {
    axios({
      url: `https://jsonplaceholder.typicode.com/users`,
      method: "GET"
    })
    .then(res => { 
      this.setState({
        users: res.data
      });
    })
    .catch(error => {
      console.log(error);
    }) 
  }

  scroll = (e) => {
    const page = this.state.page;
    const bottom = e.target.scrollHeight - e.target.scrollTop === e.target.clientHeight;
    if (bottom) { 
      alert('bottom');
      this.getUsers()

      this.setState({
        page: this.state.page + 1
      })
    }

    const top = e.target.scrollTop; 

     if(top === 0 && page > 1) {
        alert('I AM AT THE TOP');

         this.setState({
          page: this.state.page - 1
        })
      }
  }

  render() {
    console.log(this.state.page)
     console.log(this.state.users)
    return (
      <div>
         <div onScroll={this.scroll} className="container">
            <ul>
              {this.state.users.map((user, index) => 
                <li>
                  {user.name}
                </li>   
              )}
            </ul>
         </div>
      </div>
    );
  }
}

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

Here I've updated your code, slightly simplified, but mostly your code with the key points commented.在这里,我更新了您的代码,稍微简化了一些,但主要是您的代码注释了关键点。

class App extends Component {
  state = {
    users: [],
    page: 1
  };

  componentDidMount() {
    this.getUsers();
  }

  getUsers = () => {
    axios({
      url: `https://jsonplaceholder.typicode.com/users`,
      method: "GET"
    })
    .then(res => { 
      this.setState({
        // *you must append to users in state, otherwise 
        // the list will not grow as the user scrolls
        users: [...this.state.users, ...res.data],
        page: this.state.page + 1
      });
    })
    .catch(error => {
      console.log(error);
    }) 
  }

  scroll = (e) => {
    // *simplified, to only handle appending to the list
    // note the 50px from the bottom, adjust as required
    // so that the request is made before the users reaches
    // the bottom of the page under normal scrolling conditions.  
    if (e.target.scrollHeight - e.target.scrollTop <= e.target.clientHeight + 50) { 
      this.getUsers();
    }
  }

  render() {
    return (
      <div onScroll={this.scroll} className="container">
        <ul>
          {this.state.users.map((user, index) =>
            // *always add a unique key for each item
            <li key={user.name}>
              {user.name}
            </li>   
          )}
        </ul>
      </div>
    );
  }
}

All you need to do is decide when to call get users.您需要做的就是决定何时调用 get 用户。

ie if you want it to be called when you have already scrolled through 70% the height then the factor would be 0.3 (30%)即,如果您希望在已经滚动到高度的 70% 时调用它,那么该系数将为 0.3 (30%)

Whenever the scroll exceeds the 70% mark this.getusers() would be called.每当滚动超过 70% 标记时,就会调用this.getusers()

Check out how I have modified the same condition written by you.看看我是如何修改你写的相同条件的。

Rest of the code remains the same其余代码保持不变

import React, { Component } from 'react';
import { render } from 'react-dom';
import Hello from './Hello';
import './style.css';
import axios from 'axios';

class App extends Component {
  constructor() {
    super();
    this.state = {
      users: [],
      page: 1
    };
  }

  componentDidMount() {
    this.getUsers();
  }

  getUsers = () => {
    axios({
      url: `https://jsonplaceholder.typicode.com/users`,
      method: "GET"
    })
    .then(res => { 
      this.setState({
        users: res.data
      });
    })
    .catch(error => {
      console.log(error);
    }) 
  }

  scroll = (e) => {
    const page = this.state.page;
    const bottom = e.target.scrollHeight - e.target.scrollTop < e.target.clientHeight-0.3*e.target.clientHeight;
    if (bottom) { 
      alert('bottom');
      this.getUsers()

      this.setState({
        page: this.state.page + 1
      })
    }

    const top = e.target.scrollTop; 

     if(top === 0 && page > 1) {
        alert('I AM AT THE TOP');

         this.setState({
          page: this.state.page - 1
        })
      }
  }

  render() {
    console.log(this.state.page)
     console.log(this.state.users)
    return (
      <div>
         <div onScroll={this.scroll} className="container">
            <ul>
              {this.state.users.map((user, index) => 
                <li>
                  {user.name}
                </li>   
              )}
            </ul>
         </div>
      </div>
    );
  }
}

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

This lib should do the trick for you这个应该为你做的伎俩

$ yarn add react-infinite-scroller

Very simple to implement实施起来非常简单

<InfiniteScroll
  pageStart={0}
  loadMore={this.getUsers()}
  hasMore={this.state.hasMoreUsers}
  loader={<div key={0}>loading ...</div>}
> 
  <li>
    {user.name}
  </li>
</InfiniteScroll>

Don't forget to import the lib in your component file不要忘记在组件文件中导入 lib

import InfiniteScroll from 'react-infinite-scroller';

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM