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

标签 javascript firebase react-native

目的是在 FlatList 中显示帖子列表。我创建了一个自定义“Post”组件来保存每个变量。我已经通过 Postman 运行数据库 URL 并检索了数据。我想知道我的代码或 React Native 本身是否有问题?

react-native-cli:2.0.1 react native :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',
  },
});

最佳答案

我认为代码中有很多问题(至少就我对 React Native 和 Firebase 如何工作的理解而言!)

我添加了很多评论。希望这是有道理的:

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'
  }
});

关于javascript - 我在 React-Native 中渲染 Firebase 数据时遇到问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60851432/

相关文章:

javascript - IE9 没有运行 javascript onload

java - 添加 firebase 与 google play 服务冲突

javascript - 使用 CSS 样式化输入字段的占位符

javascript - 将 javascript 合并到一个文件中

javascript - JS Promise 内部是如何工作的?

android - FirebaseInstanceId token 检索失败 SERVICE_NOT_AVAILABLE

android - 如何使 firebase 动态链接区分同一应用程序的免费版和付费版?

android - 在 windows 10 中找不到 tools.jar React Native Android

react-native - React native 开发人员菜单不会在 Android Studio 模拟器上显示

ios - 在 React Native 中隐藏/显示基于服务/动态地来自 json 的标签 <Text>