【问题标题】:Infinite scroll in React with previously changed setState not workingReact 中的无限滚动,之前更改的 setState 不起作用
【发布时间】:2018-01-08 22:11:56
【问题描述】:

我有一个 React 组件,它从 API 数据中获取 10 张图像。我想使用无限滚动来加载更多的10张图片。

我要做的是监听到达网站底部的事件并仅在控制台中发布nest 10图像的新网址 :)

我应该专注于获取我的url中的所有数据,还是专注于渲染和相关功能的使用?

或者问题可能是因为我在 componentDidMount 中获取数据并且我不知道如何更新整个状态?

import React from 'react';
import ReactDOM from 'react-dom';

class ViewSection extends React.Component {
    constructor(props) {
        super(props);

        this.state = { 
            image: [],
            like: [],
            location: [],
            first_name: [],
            last_name: [],
            pictureId: [0,1,2,3,4,5,6,7,8,9],
            page: 1
        };
        this.handleScroll = this.handleScroll.bind(this) // I'M MOVING DATA TO HANDLE SCROLL
    };

    handleScroll(e) {

        e.preventDefault();
        let documentHeight = document.documentElement.offsetHeight;
        let windowHeight = window.innerHeight;
        let windowScroll = window.scrollY;
        let scrollTotal = windowScroll + windowHeight;

        if (scrollTotal == documentHeight) {   

            this.setState({  page: this.state.page + 1  })
            // console.log(this.state.page);
        }
    };

    componentDidMount() {


        let urlImage = ('https://api.website.com/categories/' + this.props.params.sectionId +  '/photos/?client_id=MYID&page=' +    this.state.page); // MAP ALL PAGES?????

        window.addEventListener("scroll", this.handleScroll,false); 

        fetch(urlImage)
        .then(resp => resp.json())
        .then(response => {

            // console.log(response);
            // console.log(this.state.page);

            let arrayOfImages = response.map((item) => item.urls.small );
            let arrayOfLikes = response.map((item) => item.likes );
            let arrayOfLoc = response.map((item) => item.user.location );
            let arrayOfFirst_Names = response.map((item) => item.user.first_name );
            let arrayOfLast_Names = response.map((item) => item.user.last_name );

            this.setState ({
                image : arrayOfImages,
                like : arrayOfLikes,
                location : arrayOfLoc,
                first_name : arrayOfFirst_Names,
                last_name : arrayOfLast_Names
            })
        });
    };

    componentWillUnmount() {
        window.removeEventListener('scroll', this.handleScroll,false);
    };

    render() {

        // console.log(this.state.image);
        console.log(this.state.page); // LISTENS AND RENDERS ALL CHANGES... MAYBE PROMISE.ALL ON    urlImage...?

        let section = this.state.image.map((elem, i, page) => {

            return (
                <Link key={i}  onScroll={this.handleScroll} className="section-picture" to= {`/section/${this.props.params.sectionId}/picture/${this.state.pictureId[i]}`}>
                    <img className="image" src={elem} alt="" />
                     <div className="section-picture-stats">
                        <div className="section-picture-stat"> author: {this.state.first_name[i]}   {this.state.last_name[i]}</div>
                        <div className="section-picture-stat">{this.state.like[i]}  like(s)</div>
                        <div className="section-picture-stat">{this.state.location[i]}
                        </div>
                    </div>
                </Link>
            )
        });

        return (
            <div className="gallery">
                <h1>Section</h1>
                <div className="buttons">
                    <div className="sort-clicks click">sort by: <a className="click" href="">new</a>    or <a className="click" href="#">trending</a></div> <Link className="click"    to='/'>back</Link>
                </div>
                <div className="section-picture-list">{section}</div>
            </div>
        )
    };
};

export { ViewSection }

【问题讨论】:

    标签: javascript reactjs fetch infinite-scroll setstate


    【解决方案1】:

    在我看来section 的值将是映射空数组的结果,因为this.state.image 将是空的,直到 componentDidMount 中的提取完成。尝试在您的渲染函数中添加一个检查,如下所示:

    let section;
    if (this.state.images.length === 0) section = <p>Loading...</p>;
    else section = this.state.image.map((elem, i, page) => {
      ...your code goes here...
    });
    

    这样它至少应该在初始渲染时正确更新

    【讨论】:

    • 哈!这看起来很有希望!但是,这仍然行不通。
      我检查了 this.state.image 是如何工作的,这是我的想法。第一次尝试时,console.log 在以下两种情况下都显示“this.state.image.length” = 0。

      1. 如果我评论了这一行
      {section}
      <br> 一段时间后,console.log 显示 <b>10</b>。酷!<br><br> 2. 但是上面这行,当我通常尝试渲染图像时,调试器会说:**“Uncaught TypeError: Cannot read property 'length' of undefined”**.... :(
    • 抱歉,格式很糟糕,我试图以最好的方式看待这个:) 我是新来的。
    猜你喜欢
    • 1970-01-01
    • 2015-01-29
    • 2013-02-17
    • 1970-01-01
    • 1970-01-01
    • 2014-03-14
    • 2013-07-05
    • 2018-10-22
    相关资源
    最近更新 更多