Ivan Burzakovskyi
Ivan Burzakovskyi

Reputation: 695

Create a React component for each element on JSON

I need consultation with rendering React components for each element in JSON (in this case - Firebase database). I'm trying to create an array of book's data and push it to an array bookKeysArray which then I will use for mapping.

As a result I get error that component ListOfUserBooks doesn't return anything (bookComponent is undefined).

Does anyone have any suggestions?

function ListOfUserBooks(props) {
    currentUserId = firebase.auth().currentUser.uid;
    userBooksDataRef = firebase.database().ref('booksData/').child(currentUserId);
    let bookKeysArray = [],
        bookComponent;

    userBooksDataRef.once('value')
            .then((snapshot) => {
                snapshot.forEach((childSnapshot) => {
                    bookKey = childSnapshot.key;
                    bookData = childSnapshot.val();
                    description = bookData.description;
                    ...

                    let bookDataArray = [description, ...];
                    bookKeysArray.push(bookDataArray);

                    bookComponent = bookKeysArray.map((book, index) => {
                            <ListOfUserBooks_ListView key = {index}
                                                       description = {book.description}
                                                       .../>
                        });
                    }
                });
            });
     return bookComponent;
};

Firebase data structure

enter image description here

Upvotes: 1

Views: 568

Answers (1)

Nicol&#242; Fuccella
Nicol&#242; Fuccella

Reputation: 41

The execution of the .then is asynchronous. So you are actually returning bookComponent before having even populated it. In react development operations such retrieving data from FireBase are executed in a lifecycle hook to populate the state and then render it. You can easily accomplish this using a class component:

class ListOfUserBooks extends React.Component {
  constructor(...args) {
    super(...args)
    this.state = { bookKeysArray: [] }
  }

  componentDidMount() {
    currentUserId = firebase.auth().currentUser.uid;
    userBooksDataRef = firebase.database().ref('booksData/').child(currentUserId);
    userBooksDataRef.once('value')
      .then((snapshot) => {
         bookKeysArray = []
         snapshot.forEach((childSnapshot) => {
           bookKey = childSnapshot.key;
           bookData = childSnapshot.val();
           description = bookData.description;
           ...
           bookKeysArray.push([description, ...]);
         })
         this.setState({ bookKeysArray })
  }

  render() {
    return this.state.bookKeysArray.map((book, index) => {
      return <ListOfUserBooks_ListView key = {index} .../>
    });
  }
}

Upvotes: 1

Related Questions