无法使用 this.state.data.map() 在 react native firebase 中显示获取的数据

Posted

技术标签:

【中文标题】无法使用 this.state.data.map() 在 react native firebase 中显示获取的数据【英文标题】:Unable to display fetched data in react native firebase using this.state.data.map() 【发布时间】: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 进行搜索的基本了解。非常感谢你

【问题讨论】:

【参考方案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>
        );
    

【讨论】:

以上是关于无法使用 this.state.data.map() 在 react native firebase 中显示获取的数据的主要内容,如果未能解决你的问题,请参考以下文章

从 JSON 对象反应渲染 HTML 对象

React Native - 来自 JSON 的地图数据可以显示为文本,但不能显示为地图标记坐标

如何在反应中映射索引范围?

SQL Server 2000无法使用

无法访问您试图使用的功能所在的网络位置

无法使用 StorageClass 配置卷 - 无法获取存储帐户的存储密钥