0

I am creating an infinite scroll with the react-infinite-scroll-component package. my scroll is working but I am having problems with the update array to add more data to the scroll content.

note: set.setState( { PostsAtt: set.state.PostsAtt.push({ data: doc.data(), id: doc.id }) } );

when I use concat () I can add the items completely, but I can't use any functions within these posts that I'm trying to return.

I looked for something specific here in the community but i didn't find anything to help me.

constructor(props) {
    super(props);  
    this.state = {
      PostsAtt: [],
    }
this.InfScroll = this.InfScroll.bind(this);
this.getDocs = this.getDocs.bind(this);

componentDidMount:

componentDidMount() {    
    // get firestore docs;
    this.getDocs();
  }

infiniteScroll Function with return more data.

InfScroll() {
    let db = firebase.firestore()
    let set = this;
    let lastVisible;

    var first = db.collection('newPost').orderBy("createdAt",'desc').limit(set.state.PostsAtt.length)        
    return first.get().then(function (documentSnapshots) {
    lastVisible = documentSnapshots.docs[documentSnapshots.docs.length - 1];   
      
    var next = db.collection('newPost').orderBy('createdAt','desc').startAfter(lastVisible).limit(3)
        next.get().then(documentSnapshots => {
        documentSnapshots.forEach( (doc) => {
          set.setState( { PostsAtt: set.state.PostsAtt.push({ data: doc.data(), id: doc.id }) } );                       
        });                      
      });                   
    })
  }

show Posts function

getDocs() {
    let db = firebase.firestore();
    let set = this;

    db.collection("newPost").orderBy('createdAt', 'desc').limit(3).onSnapshot( documentSnapshots => { 
      let PostsAtt = []           
      documentSnapshots.forEach( doc => {
        PostsAtt.push({ data: doc.data(), id: doc.id });  
      }); 
        set.setState({PostsAtt: PostsAtt});
    });    
  }

map for show posts in component.

<InfiniteScroll
          dataLength={this.state.PostsAtt.length}
          next={ this.InfScroll }
          hasMore={true}
          loader={<h4 style={{textAlign: 'center'}}>Loading...</h4>}
          height={800}
          hasChildren={true}
          endMessage={
            <p style={{ textAlign: "center" }}>
              <b>Não há mais posts.</b>
            </p>
          } >
            
          <div>
              {this.state.PostsAtt.map( (data,index) => {   
                  return (               
                  <div className="viewPost-content">
                    {index}
                    <div className="viewPost-box" key={index}
                    width={{width: '600px'}} height={{height: '505px'}}
                    style={{
                      backgroundColor: data?.data?.colorBg,
                      backgroundImage: `url(${data?.data?.url_img})`,
                      color: 'White'               
                    }}
                    >            
                    <p> <Moment to={data?.data?.createdAt?.toDate().toString()} /> </p>            
                        <h2 className="text-post"> {data?.data?.texto} </h2>                                   
                        <div class="viewPost-icons">
                          <div style={{marginRight: '-5px', marginTop: '180px', 
                            backgroundColor:'transparent'}}>             
                            <Link to={`/Posts/${data?.id}`}>
                              <i class="fas fa-comment" 
                                style={{textShadow : ' 2px 1px 1px #000000',color: 'White'}}>                          
                              </i>
                            </Link>
                          </div>
                          <div style={{marginLeft: '-15px', marginTop: '180px',
                            textShadow : '2px 1px 1px #000000'}}> { 
                          data?.data?.comentarios.length}
                          </div>
                          <div style={{marginRight: '-5px', marginTop: '176px'}}>

                            <button id="bt-Posts" onClick={() => 
                            this.UplikeFunc(data?.id,data?.data?.likes)}  
                            value={this.state.corDoLike}                                                         
                                style={{'color' : 
      data.data?.likes?.includes(firebase.auth().currentUser?.displayName) ? 'green' : 'white'}}>                            
                              <i class="fas fa-thumbs-up" style={{textShadow : ' 2px 1px 1px 
                            #000000'}}></i>
                            </button> 

                          </div>  
                          <div style={{marginLeft: '-15px', marginTop: '180px',
                            textShadow : '2px 1px 1px #000000'}}> { data?.data?.likes?.length}
                          </div>

                          <div style={{marginRight: '-5px', marginTop: '176px'}}>
                            <button id="bt-Posts" onClick={() => 
                              this.UpdislikeFunc(data?.id,data.data?.dislikes)}
                              value={this.state.corDoDislike}
                              style={{color: data?.data?.DislikeColor}}
                              >                   
                              
                              <i class="fas fa-thumbs-down" style={{textShadow : '2px 1px 1px 
                              #000000'}}></i>
                            </button>
                          </div>

                          <div style={{marginLeft: '-15px', marginTop: '180px',
                            textShadow : '2px 1px 1px #000000'}}> { data?.data?.dislikes?.length}
                          </div>                                    
                        </div>
                    </div>                
                  </div>
                    )
                  })
                }
              </div>    
        </InfiniteScroll>

2 Answers 2

1

With set.state.PostsAtt.push, you are mutating the state. Also you are setting the state inside the for loop.

Use setState callback back approach to set the state and make sure to append the data and update the state after for loop.

Like this

InfScroll = () => {
  let db = firebase.firestore();
  let set = this;
  let lastVisible;

  var first = db
    .collection("newPost")
    .orderBy("createdAt", "desc")
    .limit(set.state.PostsAtt.length);
  return first.get().then(function (documentSnapshots) {
    lastVisible = documentSnapshots.docs[documentSnapshots.docs.length - 1];

    var next = db
      .collection("newPost")
      .orderBy("createdAt", "desc")
      .startAfter(lastVisible)
      .limit(3);
    next.get().then((documentSnapshots) => {
      const postAttArr = []; //<----see here
      documentSnapshots.forEach((doc) => {
        postAttArr.push({ data: doc.data(), id: doc.id });
      });
      set.setState(prev => ({ PostsAtt: [...prev.PostsAtt, ...postAttArr] })); //<----see here
    });
  });
};

Side note:

If you don't wan't to deal with things like let set = this; , you can replace return first.get().then(function (documentSnapshots) { with an arrow function

Like this

...
var first = db
    .collection("newPost")
    .orderBy("createdAt", "desc")
    .limit(set.state.PostsAtt.length);
  return first.get().then((documentSnapshots) => { //<---- here
    lastVisible = documentSnapshots.docs[documentSnapshots.docs.length - 1];
...
Sign up to request clarification or add additional context in comments.

1 Comment

thank bro, the posts that are returned by infScroll () are not receiving an update to my like function. however posts that are not returned by infScroll () receive normally.
1

I believe the problem is over here.

set.setState( { PostsAtt: set.state.PostsAtt.push({ data: doc.data(), id: doc.id }) } );               

Array.push returns the number of items you have on the array after you push. You should push the new data outside setState, or use spread operator

const newPosts = [...set.sta.PostsAtt, { data: doc.data(), id: doc.id }]
set.setState({ PostsAtt: newPosts });

1 Comment

Thanks man, the problem of array.map is not a function has been solved, but I still can't use any functions in these posts that return. the posts that are not returned by the InfScroll () function work perfectly and I can execute the tanned function.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.