Рендеринг компонентов React, сопоставленных с Firebase Firestore - PullRequest
0 голосов
/ 20 декабря 2018

Я потратил несколько дней, пытаясь понять это, так что, надеюсь, вы сможете мне помочь.Я хочу получать сообщения из базы данных Cloud Firestore и отображать их в приложении React.

Мои данные в Firestore структурированы следующим образом:

[проект] / NewsPosts / [документы]

Каждый документ структурирован в пожарном хранилище следующим образом:

[случайно сгенерированный идентификатор]

  • title: [string]
  • body: [string]

Я получаю сообщения, выполняя следующие действия:

let posts= [];

//db = firebase.firestore();

db.collections.("NewsPosts").get().then((snapshot) => (
  snapshot.forEach((doc) => (
    posts.push({
      id: doc.id,
      title: doc.data().title,
      body: doc.data().body
    })
  ))
));

Это успешно создает массив объектов с информациейЯ хочу, так что получение данных не проблема.Однако, когда я иду на карту этого массива для создания сообщений, ничего не создается.Я пробовал каждую вариацию массивов отображения для создания компонентов, но это не работает.

Однако, когда я жестко кодирую массив объектов и сопоставляю его, он работает.Например, это работает с жестко закодированным массивом объектов:

//hard is the hardcoded array
let displayPosts = hard.map((p) => (
    <div key={p.id}>
        <h1>{p.title}</h1>
        <p>{p.body}</p>
    </div>
))

return(
    <Page>
        {displayPosts}
    </Page>
);

Когда я сравнил жестко закодированный массив и другой массив в консоли браузера, массивы выглядят по-разному.

Я полагаю, что именно эта разница в массивах вызывает проблему.

Вот так они выглядят в консоли браузера, если есть 2 элемента:

(2)[{...},{...}]      (hardcoded)
[]                    (array filled from firestore)

Однако в консоли браузера все остальное в массивах одинаковое.

Почему эти массивы выглядят по-разному?Это то, что мешает мне правильно отображать объекты в каждом индексе?Как заставить отображение работать с массивом объектов, извлеченных из Firestore?

Заранее благодарю за помощь!Это вызвало у меня сильную головную боль.

Ответы [ 3 ]

0 голосов
/ 22 декабря 2018

Я решил это!

Я не изменил это неизменным образом.

Это заставляет его работать правильно:

constructor(props){
    super(props);

    this.state = {
        posts: []
    }
}

componentDidMount = () => {
    db.collection("NewsPosts").get().then((snapshot) => (
        snapshot.forEach((doc) => (
            this.setState((prevState) => ({
                posts: [...prevState.posts, {
                    postID: doc.id,
                    title: doc.data().title,
                    body: doc.data().body,
                    featured: doc.data().featured
                }]
            }))
        ))
    ))
}
0 голосов
/ 31 июля 2019

В вашем ответе на ваш вопрос по-прежнему отсутствует правильный ключ.Таким образом, полный ответ на вопрос Манго (и собственный ответ) будет:

class Sample extends React.Component {

constructor(props){
  super(props);

  this.state = {
    posts: []
  }
}

componentDidMount = () => {
    db.collection("NewsPosts").get().then((snapshot) => (
        snapshot.forEach((doc) => (
            this.setState((prevState) => ({
                posts: [...prevState.posts, {
                    postID: doc.id,
                    title: doc.data().title,
                    body: doc.data().body,
                    featured: doc.data().featured
                }]
            }))
        ))
    ))
}

    render() {
        let displayPosts = this.state.posts.map((p) => (
            <div key={p.postID}>
                <h1>{p.title}</h1>
                <p>{p.body}</p>
            </div>
        ))

        return(
            <Page>
                {displayPosts}
            </Page>
        );
    }

}
0 голосов
/ 20 декабря 2018

Исходя из моего понимания вашего вопроса, я думаю, что следующий код должен помочь вам решить вашу проблему.

class Sample extends React.Component {

    state = {
        posts: []
    }

    componentDidMount() {
        let posts = [];
        db.collections.("NewsPosts").get().then((snapshot) => (
            snapshot.forEach((doc) => (
                posts.push({
                    id: doc.id,
                    title: doc.data().title,
                    body: doc.data().body
                })
            ))
            this.setState({ posts })
        ));
    }

    render() {
        let displayPosts = this.state.posts.map((p) => (
            <div key={p.id}>
                <h1>{p.title}</h1>
                <p>{p.body}</p>
            </div>
        ))

        return(
            <Page>
                {displayPosts}
            </Page>
        );
    }

}

Главное, что этот код выделяет, это то, что реакция основана на данных.По сути, у вас есть массив состояний, называемый постами, который вы будете отображать для отображения ваших данных.Когда этот массив пуст, как в случае до извлечения данных, как при первоначальном рендеринге, никакие элементы не будут отображаться.Как только данные возвращаются из БД, они добавляются в массив сообщений о состоянии.Метод setState вызывается для принудительного создания нового рендера, но на этот раз у нас есть данные для отображения.

Если этот ответ показывает, что я неправильно понял ваш вопрос, пожалуйста, продолжайте.

Надеюсь, что этопомогает!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...