M
M
MarEeeeeee2021-04-30 17:35:41
React
MarEeeeeee, 2021-04-30 17:35:41

How to render data that comes asynchronously?

Hello. I am getting data from the database. It is required to draw the elements as soon as they are received. I don't understand how to do it.
My component looks like this

import React from 'react'
import  firebase from 'firebase';


class ListOfLecture extends React.Component{
    constructor(props) {
        super(props)
        this.state = {
            lectures:{},
            isLoading: false,
        }                    
      }



      async componentDidMount(){
        this.setState({
            lectures:(await firebase.database().ref('lectures/').once('value')).val(),
            isLoading: true
        }); 
    }


      render(){
          return(
              <div>
                  {
                     Object.keys(this.state.lectures).fill().map( (item,i)=>{
                         console.log(item, i)
                         return(<span key = {i}>{item}</span>)
                     })
                  
                  }
              </div>
          )
      }
}
export default ListOfLecture;

The value inside item is undefined. I understand why this is happening, but I don't understand how to fix it

Answer the question

In order to leave comments, you need to log in

1 answer(s)
T
tehfreak, 2021-05-03
@MarEeeeeee

Here is the full version of the required component with loading indicator and error handling:

class Lectures extends React.PureComponent {

    state = {
        lectures: null,
        lecturesError: null,
        lecturesPending: true,
    }

    async componentDidMount() {
        await this.fetchLectures()
    }

    async fetchLectures() {
        this.setState({ lectures:null, lecturesError:null, lecturesPending:true })
        try {
            const lectures = (await firebase.database().ref('lectures').once('value')).val()
            console.log(lectures)
            this.setState({ lectures, lecturesError:null, lecturesPending:false })
        } catch (lecturesError) {
            console.error(lecturesError)
            this.setState({ lectures:null, lecturesError, lecturesPending:false })
        }
    }

    render() {
        const { lectures, lecturesError, lecturesPending } = this.state
        return (
            <section>
                <h1>Лекции</h1>
                {lecturesPending && (
                    <div>Загружаются...</div>
                )}
                {lecturesError != null && (
                    <div>Не удалось загрузить: {lecturesError.message}</div>
                )}
                {lectures != null && (
                    <ul>
                        {lectures.map((lecture) => (
                            <li
                                key={lecture.id}
                            >
                                {lecture.name}
                            </li>
                        ))}
                    </ul>
                )}
            </section>
        )
    }
}

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question