Невозможно отобразить полученные данные в встроенной базе Firebase с использованием this.state.data.map ()

Я боролся с отображением элемента базы данных на моей странице, используя 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. Большое спасибо

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
334
2

Ответы 2

Если я правильно понимаю, вам нужен правильный способ отображения ваших данных. Поскольку 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>
    )
}

Спасибо за быстрый ответ, отображается ошибка. 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)

Abdulkabir Ojulari 17.12.2018 20:36

Да, он отображается, но текстовый ввод не разрешен для записи нового элемента, а функция удаления не работает. Также есть предупреждение: VirtualizedList: отсутствуют ключи для элементов, не забудьте указать свойство ключа для каждого элемента или предоставить настраиваемый keyExtractor. Спасибо

Abdulkabir Ojulari 17.12.2018 21:01

Эээ, я не трогал эту часть кода, но я посмотрю

Milore 17.12.2018 21:04

Хорошо, спасибо, я буду ждать. Есть ли какой-нибудь учебник, который вы можете порекомендовать?

Abdulkabir Ojulari 17.12.2018 21:43

К сожалению, времени у меня мало. Я заметил, что функция удаления вообще некорректна, но TextInput кажется допустимым. Предлагаю вам прочитать официальную документацию, она хороша и полна примеров, которые могут вам помочь. Удачи! И я был бы признателен, если бы вы рассмотрели вопрос о том, чтобы проверить этот ответ (так как он, на мой взгляд), или, может быть, просто немного проголосовали за: D

Milore 17.12.2018 21:53

Спасибо за поддержку. Я просмотрел свой код, и он работает отлично, как я хочу. Я буду рад опубликовать это здесь на случай, если кому-то еще понадобится поработать или узнать об этом. Я использовал функцию 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>
        );
    }
}

Другие вопросы по теме