#javascript #reactjs #firebase #react-native #expo
# #javascript #reactjs #firebase #реагировать-родной #expo
Вопрос:
Я работаю над приложением ToDo, которое подключено к базе данных Firebase в реальном времени. Все работает нормально. Я также могу хранить данные в базе данных Firebase, но проблема в том, что я не могу получить какие-либо данные из базы данных. Я хочу отображать данные в ScrollView, чтобы данные могли отображаться в ScrollView при открытии моего приложения.
Main.js
import React, { Component } from 'react';
import {
StyleSheet,
Text,
View,
TextInput,
ScrollView,
TouchableOpacity
} from 'react-native';
import Note from './Note';
import firebase from './firebase';
export default class Main extends React.Component {
constructor(props) {
super(props);
this.state = {
noteArray: [],
noteText: ''
}
}
render() {
let notes = () => {
firebase.database().ref(`todos`).on('value', function (snapshot) {
return <Note key={snapshot.val().key} keyval={snapshot.val().key} val={snapshot.val().note}
deleteMethod={() => this.deleteNote(key)}
/>
});
}
return (
<View style={styles.container}>
<View style={styles.header}>
<Text style={styles.headerText}>Todo</Text>
</View>
<ScrollView style={styles.scrollContainer}>
{notes}
</ScrollView>
<View style={styles.footer}>
<TextInput
style={styles.textInput}
onChangeText={(noteText) => this.setState({ noteText })}
value={this.state.noteText}
placeholder='Enter Task'
placeholderTextColor='white'
underlineColorAndroid='transparent'>
</TextInput>
</View>
<TouchableOpacity onPress={this.adTask.bind(this)} style={styles.addButton}>
<Text style={styles.addButtonText}>Add</Text>
</TouchableOpacity>
</View>
);
}
adTask() {
if (this.state.noteText) {
var date = new Date();
var database = firebase.database().ref('todos');
var key = database.push().key;
var todo = {
'date': date.getDay()
'/' (date.getMonth() 1)
'/' date.getFullYear(),
'note': this.state.noteText,
key: key
}
database.child(key).set(todo);
this.setState({ noteArray: this.state.noteArray });
this.setState({ noteText: this.state.noteText });
this.setState({
noteText: this.state.noteText = ""
})
}
}
note.js
import React from 'react';
import { StyleSheet, Text, View, TouchableOpacity } from 'react-native';
import { AntDesign } from '@expo/vector-icons';
export default class Main extends React.Component {
render() {
return (
<View key={this.props.keyval} style={styles.note}>
<Text style={styles.noteText}>{this.props.val.note}</Text>
<Text style={styles.noteDate}>{this.props.val.date}</Text>
<TouchableOpacity onPress={this.props.deleteMethod} style={styles.noteDelete}>
<Text style={styles.noteDeleteText}><AntDesign name="delete" size={24} color="black" /></Text>
</TouchableOpacity>
</View>
);
}
}
Ответ №1:
Вы удалили переменную состояния noteArray, но вы ее вообще не используете. В идеале вы должны настроить прослушиватель изменений данных realtime database
и обновлять свое локальное состояние при изменении данных. Вы можете настроить функцию прослушивания и вызвать ее внутри вашего Main.js
componentDidMount
метода жизненного цикла файла.
Внутри этой функции вы можете обновить свое локальное состояние noteArray
значением, полученным из базы данных в реальном времени. Затем вы можете отобразить noteArray для отображения ваших заметок в вашем приложении с помощью scrollview. Я бы лично посоветовал вам использовать FlatList
реализацию react native в этом случае, поскольку этот массив заметок может расти со временем. Это поможет вам избежать проблем с производительностью, с которыми вы можете столкнуться в случае длинного списка и scrollview.
Main.js
import React, { Component } from 'react';
import {
StyleSheet,
Text,
View,
TextInput,
ScrollView,
TouchableOpacity,
FlatList
} from 'react-native';
import Note from './Note';
import firebase from './firebase';
export default class Main extends React.Component {
constructor(props) {
super(props);
this.state = {
noteArray: [],
noteText: ''
}
}
componentDidMount() {
this.listenForNotes()
}
listenForNotes() {
firebase.database().ref(`todos`).on('value', function (snapshot) {
const notes = [];
snapshot.forEach(child => {
notes.push({
note: child.val().name,
date: child.val().date,
key: child.key
});
});
this.setState({
noteArray: notes
});
});
}
adTask() {
if (this.state.noteText) {
var date = new Date();
var database = firebase.database().ref('todos');
var key = database.push().key;
var todo = {
'date': date.getDay()
'/' (date.getMonth() 1)
'/' date.getFullYear(),
'note': this.state.noteText,
key: key
}
database.child(key).set(todo);
this.setState({ noteText: "" });
}
}
deleteNote(key) {
// your delete note function
}
render() {
return (
<View style={styles.container}>
<View style={styles.header}>
<Text style={styles.headerText}>Todo</Text>
</View>
<FlatList
data={noteArray}
renderItem={({ item, index }) => {
return (
<Note
key={item.key}
note={item.note}
date={item.date}
deleteMethod={() => this.deleteNote(key)}
/>
);
}}
key={(item) => `${item.key}`}
/>
<View style={styles.footer}>
<TextInput
style={styles.textInput}
onChangeText={(noteText) => this.setState({ noteText })}
value={this.state.noteText}
placeholder='Enter Task'
placeholderTextColor='white'
underlineColorAndroid='transparent'>
</TextInput>
</View>
<TouchableOpacity onPress={this.adTask.bind(this)} style={styles.addButton}>
<Text style={styles.addButtonText}>Add</Text>
</TouchableOpacity>
</View>
);
}
}
Вы также должны внести некоторые изменения в Note.js
файл, чтобы отобразить переданные реквизиты.
Note.js
import React from 'react';
import { StyleSheet, Text, View, TouchableOpacity } from 'react-native';
import { AntDesign } from '@expo/vector-icons';
export default class Note extends React.Component {
constructor(props) {
super(props);
}
render() {
const { note, date, key, deleteMethod } = this.props;
return (
<View key={key} style={styles.note}>
<Text style={styles.noteText}>{note}</Text>
<Text style={styles.noteDate}>{date}</Text>
<TouchableOpacity onPress={deleteMethod} style={styles.noteDelete}>
<Text style={styles.noteDeleteText}><AntDesign name="delete" size={24} color="black" /></Text>
</TouchableOpacity>
</View>
);
}
}
Комментарии:
1. Я получаю ошибку в компоненте FlatList, которая выглядит так: ReferenceError: noteArray не определен <FlatList data={noteArray} когда я меняю его на data={this.state.noteArray}, это выдает другую ошибку: TypeError: не удается прочитать свойство ‘setState’ null: this.setState({noteArray: примечания });
2. что мне теперь делать?
3. Я загрузил весь свой код здесь для тестирования, пожалуйста, проверьте: codesandbox.io/s/stupefied-snowflake-1lddp?file=/src/App.js