【问题标题】:Unable to display fetched data in react native firebase using this.state.data.map()无法使用 this.state.data.map() 在 react native firebase 中显示获取的数据
【发布时间】:2018-12-17 17:51:51
【问题描述】:

我一直在使用 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.log(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 和使用 React 原生 firebase 进行搜索的基本了解。非常感谢你

【问题讨论】:

    标签: ios firebase react-native


    【解决方案1】:

    如果我正确理解您需要一种正确的方式来显示您的数据。由于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: Cannot read property 'date' of undefined 此错误位于:在 CellRenderer (at VirtualizedList.js:687) in RCTScrollContentView (at ScrollView.js:852) in RCTScrollView (at ScrollView.js:977) in ScrollView (at VirtualizedList.js:1062) 在 VirtualizedList (在 FlatList.js:663) 在 FlatList (在 Main.js:80)
    • 是的,它显示了,但 textinput 没有启用写入新项目,并且删除功能不起作用。还有一个警告:VirtualizedList:缺少项目的键,请确保在每个项目上指定键属性或提供自定义 keyExtractor。谢谢
    • 呃,那部分代码我没碰过,不过我看看
    • 好的,谢谢,我会期待的。有什么教程可以推荐
    • 很遗憾,我的时间不多了。我注意到删除功能根本不正确,但 TextInput 似乎有效。我建议您阅读官方文档,它很好并且充满了可以帮助您的示例。祝你好运!如果您考虑检查这个答案(因为在我看来)或者只是一点点赞,我将不胜感激:D
    【解决方案2】:

    感谢您的支持。我已经查看了我的代码,它可以按我的意愿完美运行。我很乐意把它贴在这里,以防其他人需要工作或了解它。我使用 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.log(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});
        }
    
    }
    

    我有另一个名为 Note.js 的 .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>
            );
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2018-11-07
      • 1970-01-01
      • 1970-01-01
      • 2021-04-06
      • 1970-01-01
      • 2021-11-27
      • 1970-01-01
      • 1970-01-01
      • 2018-03-07
      相关资源
      最近更新 更多