开发者问题收集

从 Firestore 获取数据

2018-10-18
16663

因此,我尝试从 Firestore 获取数据,当我控制台记录它时,我得到了我的集合的内容,但是当我将代码移动到函数时,我无法将其返回。

此代码有效:

const db = firebase.firestore();
db.settings({ timestampsInSnapshots: true});
db.collection('story').get().then((snapshot) => {
snapshot.docs.forEach(doc => {console.log(doc.data())
    ;})
})

这不起作用。(它编译,但没有返回任何内容):

...
getMyStory = () => {
        const db = firebase.firestore();
        db.settings({ timestampsInSnapshots: true});
        db.collection('story').get().then((snapshot) => {
        snapshot.docs.forEach(doc => {
            let items = doc.data();
        })
        });
        return this.items;
    }


    render () {


        return (
        <p>{this.getMyStory}</p>
);
}

我做错了什么?

3个回答

您的渲染逻辑将需要考虑对 Firebase 的异步查询。考虑利用组件 state 来解决此问题,方法是对您的代码进行以下调整:

getMyStory() { /* Remove arrow function */

    const db = firebase.firestore();
    db.settings({ timestampsInSnapshots: true});
    db.collection('story').get().then((snapshot) => {

      snapshot.docs.forEach(doc => {
          let items = doc.data();

          /* Make data suitable for rendering */
          items = JSON.stringify(items);

          /* Update the components state with query result */
          this.setState({ items : items }) 
      });

    });
}

接下来,将 componentDidMount() 添加到您的组件,然后添加对 getMyStory() 的调用,如下所示:

componentDidMount() {

    /* Cause your component to request data from Firebase when
       component first mounted */
    this.getMyStory()
}

最后,更新您的渲染方法以使用状态,而不是方法:

  render () {

    return (<p>{ this.state.items || 'Loading' }</p>);
 }

希望这能有所帮助!

Dacre Denny
2018-10-18

这里的主要问题是你试图同步渲染异步数据,而这在 React ( not yet at least) 中是无法实现的。

渲染异步数据时,你通常会利用组件 state

以下是加载和渲染异步内容时的标准使用模式。

class YourComponent extends Component {
  state = {
    items: []
  }

  // This method is called when the component mounts
  // Usually  a good place to do async requests
  componentDidMount() {

    db.collection('story').get().then(snapshot => {
      // After promise is finished set data to local state
      // When setting state the render method will be called, thus rerendering the UI
      this.setState({ items: snapshot })
    })
  }

  render() {
    // Access your items from local component state
    const { items } = this.state;

    return (
      <div>
        {items.forEach(doc => {
          // Render whatever data is in your document
          return <p key={doc.id}> { Your data goes here }</p>
        })
        }
      </div>
    )
  }
}
Tsuni
2018-10-18

The Promise object represents the eventual completion (or failure) of an asynchronous operation, and its resulting value

根据您的代码, return this.items; 先执行,然后解析 db.collection('story').get() ,最后永远得不到结果。

基本上是这一行:

db.collection('story').get()

这是一个承诺,然后你必须等待解决结果,下面的代码:

getMyStory = () => {
    const db = firebase.firestore();

    db.settings({ timestampsInSnapshots: true});

    return db.collection('story').get()
}

阅读更多关于承诺的内容

==========================EDIT============================

getMyStory().then((snapshot) => {
    const listItems = snapshot.map((element) =>
      <li>{element}</li>
    );

    ReactDOM.render(
      <ul>{listItems}</ul>,
      document.getElementById('root')
    );
});

了解有关地图的更多信息

ene_salinas
2018-10-18