Я боролся с отображением элемента базы данных на моей странице, используя this.state.noteArray.map (val, key). Я намерен отображать каждое значение с помощью кнопки удаления, чтобы удалить его со страницы.
import React, { Component } from 'react';
import {
View,
Text,
StyleSheet,
TextInput,
ScrollView,
TouchableOpacity
} from 'react-native';
import firebase from 'firebase';
// Initialize Firebase
const config = {
apiKey: "XXXXXXXXXXXXXXX",
authDomain: "XXXXXXXXXXXXXXXXXXXXXX",
databaseURL: "XXXXXXXXXXXXXXXXXXXXXXXX",
projectId: "XXXXXXXXXXXXXXXXXXXXXX",
storageBucket: "",
messagingSenderId: "XXXXXXXXXXXXXXXXXXXX"
};
firebase.initializeApp(config);
export default class Main extends Component {
constructor(props){
super(props);
this.state = {
noteArray: [],
noteText: '',
};
this.addNote = this.addNote.bind(this);
}
componentDidMount(){
firebase.database()
.ref()
.child("todo")
.once("value", snapshot => {
const data = snapshot.val()
if (snapshot.val()){
const initNoteArray = [];
Object
.keys(data)
.forEach(noteText => initNoteArray.push(data[noteText]));
this.setState({
noteArray: initNoteArray
});
}
});
firebase.database()
.ref()
.child("todo")
.on("child_added", snapshot => {
const data = snapshot.val();
if (data){
this.setState(prevState => ({
noteArray: [data, ...prevState.noteArray]
}))
console.info(this.state.noteArray);
}
})
}
addNote(){
// firebase function here to send to the database
if (!this.state.noteText) return;
var d = new Date();
const newNote = firebase.database().ref()
.child("todo")
.push ({
'date':d.getFullYear()+
"/"+(d.getMonth()+1) +
"/"+ d.getDate(),
'note': this.state.noteText
});
newNote.set(this.state.noteText, () => this.setState({noteText: ''}))
}
render() {
let notes = this.state.noteArray.map((val, key)=>{
return
(<View key = {key} keyval = {key} val = {val} style = {styles.note}>
<Text style = {styles.noteText}>{this.state.val.date}</Text>
<Text style = {styles.noteText}>{this.state.val.note}</Text>
<TouchableOpacity onPress = {this.state.deleteMethod} style = {styles.noteDelete}>
<Text deleteMethod = {()=>this.deleteNote(key)} style = {styles.noteDeleteText}>D</Text>
</TouchableOpacity>
</View>)
});
return (
<View style = {styles.container}>
<View style = {styles.header}>
<Text style = {styles.headerText}>Todo App</Text>
</View>
<ScrollView style = {styles.scrollContainer}>
{notes}
</ScrollView>
<View style = {styles.footer}>
<TextInput
style = {styles.textInput}
placeholder='>note'
onChangeText = {(noteText)=> this.setState({noteText})}
value = {this.state.noteText}
placeholderTextColor='white'
underlineColorAndroid='transparent'>
</TextInput>
</View>
<TouchableOpacity onPress = { this.addNote } style = {styles.addButton}>
<Text style = {styles.addButtonText}>+</Text>
</TouchableOpacity>
</View>
);
}
deleteNote(key){
this.state.noteArray.splice(key, 1);
this.setState({noteArray: this.state.noteArray});
}
}
Предупреждений или ошибок нет, но ничего не отображается. Я буду признателен, если в следующий раз будет какая-либо помощь и встроенный комментарий, чтобы понять процесс. Я новичок, пытаюсь освоить код для будущих подобных проектов. Все, что мне нужно знать, - это базовое понимание CRUD и поиска с использованием собственной Firebase React. Большое спасибо
Если я правильно понимаю, вам нужен правильный способ отображения ваших данных. Поскольку noteArray - это массив, нет ничего проще, чем FlatList, который сам по себе прокручивается. Итак, в вашем методе рендеринга:
render() {
return (
<View style = {styles.container}>
<FlatList
data = {this.state.noteArray} // Here is where you pass your array of data
renderItem = {this.renderItem} // Here is how to display each item of your data array
ListHeaderComponent = {this.renderHeader}
ListFooterComponent = {this.renderFooter}
/>
</View>
);
}
Где:
renderHeader = () => {
return (
<View style = {styles.header}>
<Text style = {styles.headerText}>Todo App</Text>
</View>
)
}
renderFooter = () => {
return (
<View>
<View style = {styles.footer}>
<TextInput
style = {styles.textInput}
placeholder='>note'
onChangeText = {(noteText)=> this.setState({noteText})}
value = {this.state.noteText}
placeholderTextColor='white'
underlineColorAndroid='transparent'>
</TextInput>
</View>
<TouchableOpacity onPress = { this.addNote } style = {styles.addButton}>
<Text style = {styles.addButtonText}>+</Text>
</TouchableOpacity>
</View>
)
}
renderItem = ({ item, index }) => {
return (
<View key = {index} style = {styles.note}>
<Text style = {styles.noteText}>{item.date}</Text>
<Text style = {styles.noteText}>{item.note}</Text>
<TouchableOpacity onPress = {this.state.deleteMethod} style = {styles.noteDelete}>
<Text deleteMethod = {()=>this.deleteNote(index)} style = {styles.noteDeleteText}>D</Text>
</TouchableOpacity>
</View>
)
}
Да, он отображается, но текстовый ввод не разрешен для записи нового элемента, а функция удаления не работает. Также есть предупреждение: VirtualizedList: отсутствуют ключи для элементов, не забудьте указать свойство ключа для каждого элемента или предоставить настраиваемый keyExtractor. Спасибо
Эээ, я не трогал эту часть кода, но я посмотрю
Хорошо, спасибо, я буду ждать. Есть ли какой-нибудь учебник, который вы можете порекомендовать?
К сожалению, времени у меня мало. Я заметил, что функция удаления вообще некорректна, но TextInput кажется допустимым. Предлагаю вам прочитать официальную документацию, она хороша и полна примеров, которые могут вам помочь. Удачи! И я был бы признателен, если бы вы рассмотрели вопрос о том, чтобы проверить этот ответ (так как он, на мой взгляд), или, может быть, просто немного проголосовали за: D
Спасибо за поддержку. Я просмотрел свой код, и он работает отлично, как я хочу. Я буду рад опубликовать это здесь на случай, если кому-то еще понадобится поработать или узнать об этом. Я использовал функцию array.map () для перебора элементов.
import React, { Component } from 'react';
import {
View,
Text,
StyleSheet,
TextInput,
ScrollView,
TouchableOpacity
} from 'react-native';
import Note from './Note';
import firebase from 'firebase';
// Initialize Firebase
const config = {
apiKey: "XXXXXXXXXXXXXXXXXXXXXXXXXX",
authDomain: "XXXXXXXXXXXXXXXXXXXXXX",
databaseURL: "XXXXXXXXXXXXXXXXXXXXXXXX",
projectId: "XXXXXXXXXXXXXXXXXXXXXXXXX",
storageBucket: "",
messagingSenderId: "XXXXXXXXXXXXXXXX"
};
firebase.initializeApp(config);
export default class Main extends Component {
constructor(props){
super(props);
this.state = {
noteArray: [],
noteText: '',
};
this.addNote = this.addNote.bind(this);
}
componentDidMount(){
firebase.database()
.ref()
.child("todo")
.once("value", snapshot => {
const data = snapshot.val()
if (snapshot.val()){
const initNoteArray = [];
Object
.keys(data)
.forEach(noteText => initNoteArray.push(data[noteText]));
this.setState({
noteArray: initNoteArray
});
}
});
firebase.database()
.ref()
.child("todo")
.on("child_added", snapshot => {
const data = snapshot.val();
if (data){
this.setState(prevState => ({
noteArray: [data, ...prevState.noteArray]
}))
console.info(this.state.noteArray);
}
})
}
addNote(){
// firebase function here to send to the database
if (!this.state.noteText) return;
var d = new Date();
const newNote = firebase.database().ref()
.child("todo")
.push ();
newNote.set({
'date':d.getFullYear()+
"/"+(d.getMonth()+1) +
"/"+ d.getDate(),
'note': this.state.noteText
});
this.setState({noteText:''});
}
render() {
let notes = this.state.noteArray.map((val, key)=>{
return <Note key = {key} keyval = {key} val = {val}
deleteMethod = {()=>this.deleteNote(key)}/>
});
return (
<View style = {styles.container}>
<View style = {styles.header}>
<Text style = {styles.headerText}>Todo App</Text>
</View>
<ScrollView style = {styles.scrollContainer}>
{notes}
</ScrollView>
<View style = {styles.footer}>
<TextInput
style = {styles.textInput}
placeholder='>note'
onChangeText = {(noteText)=> this.setState({noteText})}
value = {this.state.noteText}
placeholderTextColor='white'
underlineColorAndroid='transparent'>
</TextInput>
</View>
<TouchableOpacity onPress = { this.addNote } style = {styles.addButton}>
<Text style = {styles.addButtonText}>+</Text>
</TouchableOpacity>
</View>
);
}
deleteNote(key){
this.state.noteArray.splice(key, 1);
this.setState({noteArray: this.state.noteArray});
}
}
У меня есть еще один компонент .js с именем Note.js для шаблона отображения. Он был включен в Main.js и использовался сразу после рендеринга.
import React, { Component } from 'react';
import {
View,
Text,
StyleSheet,
TouchableOpacity,
} from 'react-native';
export default class Note extends Component {
render() {
return (
<View key = {this.props.keyval} style = {styles.note}>
<Text style = {styles.noteText}>{this.props.val.date}</Text>
<Text style = {styles.noteText}>{this.props.val.note}</Text>
<TouchableOpacity onPress = {this.props.deleteMethod} style = {styles.noteDelete}>
<Text style = {styles.noteDeleteText}>D</Text>
</TouchableOpacity>
</View>
);
}
}
Спасибо за быстрый ответ, отображается ошибка. TypeError: невозможно прочитать свойство 'date' of undefined. Эта ошибка находится по адресу: в CellRenderer (в VirtualizedList.js: 687) в RCTScrollContentView (в ScrollView.js: 852) в RCTScrollView (в ScrollView.js: 977) в ScrollView (в VirtualizedList.js: 1062) в VirtualizedList (в FlatList.js: 663) в FlatList (в Main.js: 80)