简体   繁体   English

我在 React-Native 中从 Firebase 渲染我的数据时遇到问题

[英]I'm having trouble rendering my data from Firebase in React-Native

The aim is to display a list of posts in a FlatList.目的是在 FlatList 中显示帖子列表。 I've created a custom 'Post' component to hold each of the variables.我创建了一个自定义的“Post”组件来保存每个变量。 I've run the database URL through Postman and the data was retrieved.我已经通过 Postman 运行了数据库 URL 并检索了数据。 I'm wondering if there is an issue with my code or React Native itself?我想知道我的代码或 React Native 本身是否有问题?

react-native-cli: 2.0.1 react-native: 0.61.5反应原生cli:2.0.1 反应原生:0.61.5

import React, {Component} from 'react';
import {FlatList, StyleSheet, View} from 'react-native';
import Post from './Post';
import Firebase from 'firebase';
import 'firebase/firestore';
import 'firebase/database';
import {firebaseConfig} from './configFirebase';

export default class Posts extends Component {
  constructor(props) {
    super(props);
    !Firebase.apps.length
      ? Firebase.initializeApp(firebaseConfig.firebase)
      : Firebase.app();

    this.state = {
      postList: [],
    };
  }

  getPostData() {
    let ref = Firebase.database().ref('/posts');
    ref.on('value', snapshot => {
      const state = snapshot.val();
      this.setState(state);
    });
    console.log('DATA RETRIEVED');
  }

  getItemCount() {
    Firebase.database()
      .ref('/posts')
      .on('value', snapshot => {
        const postCount = snapshot.key.length;
        this.setState({postCount});
      });
  }

  renderItem() {
    const post = this.state;
    return (
      <Post
        key={post.key}
        heading={post.heading}
        description={post.description}
        location={post.location}
      />
    );
  }

  componentDidMount() {
    this.getPostData();
    this.getItemCount();
    this.renderItem();
  }

  render() {
    const {postList} = this.state;
    return (
      <View style={styles.container}>
        {postList.map(post => (
          <FlatList
            keyExtractor={post.id}
            data={this.state.postList}
            getItem={this.renderItem}
            getItemCount={this.getItemCount}
          />
        ))}
      </View>
    );
  }
}

export const styles = StyleSheet.create({
  container: {
    borderWidth: 2,
    borderRadius: 5,
    backgroundColor: '#2bb76e',
    flex: 1,
  },
  txtInput: {
    flex: 1,
    margin: 5,
    padding: 5,
    borderWidth: 2,
    fontSize: 20,
    borderRadius: 5,
    backgroundColor: 'snow',
  },
});

There were quite a few things that I think were wrong with the code (at least as far as my understanding of how react native and firebase work!)我认为代码有很多问题(至少就我对 react native 和 firebase 工作原理的理解而言!)

I've added a lot of comments.我添加了很多评论。 Hope this makes sense:希望这是有道理的:

import React, { Component } from 'react';
import { FlatList, StyleSheet, View } from 'react-native';
import Post from './Post';
import Firebase from 'firebase';
import 'firebase/firestore';
import 'firebase/database';
import { firebaseConfig } from './configFirebase';

export default class Posts extends Component {
  constructor(props) {
    super(props);
    !Firebase.apps.length ? Firebase.initializeApp(firebaseConfig.firebase) : Firebase.app();

    this.state = {
      postList: []
    };
  }

  // moved componentDidMount to top as per convention
  componentDidMount() {
    this.getPostData();
    // this.getItemCount(); // I'm pretty sure you don't need this
    // this.renderItem(); // this doesn't belong here
  }

  // use arrow function so references to 'this' are bound to the component
  getPostData = () => {
    const ref = Firebase.database().ref('/posts'); // use const. It doesn't change.
    ref.on('value', snapshot => {
      console.log('DATA RETRIEVED'); // move inside the callback, so only triggers if you do actually retrieve data
      const postsObj = snapshot.val();

      if (!postsObj) return console.warn('No data from firebase');

      const postsArr = Object.values(postsObj);

      this.setState({postList: postsArr}); 
   });
  };

  // I don't think you need getItemCount...

  // getItemCount() {
  //   Firebase.database().ref('/posts').on('value', snapshot => {
  //     const postCount = snapshot.key.length;
  //     this.setState({ postCount });
  //   });
  // }

  renderItem({ item: post, index }) {
    return (
      <Post
        key={index} // changed this to index, because your post objects don't have keys. But if you can add unique keys then that will be better!
        heading={post.heading}
        description={post.description}
        location={post.location}
      />
    );
  }

  render() {
    return (
      <View style={styles.container}>
        {/* Cleaned up FlatList... I think you got confused here */}
        <FlatList
          keyExtractor={(item, index) => index.toString()} // syntax was wrong. Fixed.
          data={this.state.postList}
          renderItem={this.renderItem}
        />
      </View>
    );
  }
}

export const styles = StyleSheet.create({
  container: {
    borderWidth: 2,
    borderRadius: 5,
    backgroundColor: '#2bb76e',
    flex: 1
  },
  txtInput: {
    flex: 1,
    margin: 5,
    padding: 5,
    borderWidth: 2,
    fontSize: 20,
    borderRadius: 5,
    backgroundColor: 'snow'
  }
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM