javascript - 我无法在 React-Native 中从 Firebase 渲染我的数据
问题描述
目的是在 FlatList 中显示帖子列表。我创建了一个自定义的“发布”组件来保存每个变量。我已经通过 Postman 运行了数据库 URL,并检索了数据。我想知道我的代码或 React Native 本身是否有问题?
反应原生 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',
},
});
解决方案
我认为代码有很多问题(至少就我对 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 - 如何使用 JavaScript 或 jQuery 防止多次点击?
- java - 为什么我的 JLabel 没有显示?
- javascript - 在 ReactJS 中使用 Real DOM 元素修改 VirtualDOM
- docker - 将 KafkaConnect 添加到现有的 Ambari 服务
- javascript - Lodash 将键的值映射到另一个键
- javascript - 从另一个网页加载命名元素
- jenkins - 如何使用带通配符的 curl 命令将工件部署到 jfrog 工件
- html - 为什么这个简单的 HTML/ASP 子菜单不起作用?
- c++ - C++:随机数列表:x 个随机整数
- javascript - 如何使用 NodeJS 运行文件夹中的所有 javascript 文件?