0

I am new to react native and was trying to display some data into a react component (preferably cards) but for now FlatList will work. I was unable to destructure the data and display it. How should it be done?

import React,{useState,useEffect} from 'react';
import { StyleSheet,Modal,  View ,Text , ScrollView, Alert} from 'react-native';
import {IconButton ,Appbar, Card,  TextInput ,Button ,
  } from 'react-native-paper';
  import firebase from './config';
  import { LogBox } from 'react-native';
  LogBox.ignoreLogs(['Setting a timer']);

export default function PlantATree(){
  const [modalVisible, setModalVisible] = useState(false);
  
  const [name,setName]=useState('');
  const [title, setTitle]=useState('');
  const [description, setDescription]=useState('');
  const [data, setmyData]=useState([])

  const savePost =  () =>{
       
      firebase.database()
      .ref('posts')
      .push({
        "id":Math.random(),
        "name":name,
        "title":title,
        "description":description,
        
      })
    setTimeout(()=>{
      Alert.alert("Your post is saved successfully :D")
    },1000)

  }

    useEffect(()=>{
      const data = firebase.database().ref("posts");
      data.on("value", datasnap =>{
        //console.log(Object.values(datasnap.val()));
        if(datasnap.val()){
        setmyData(datasnap.val());
        }
      })
    },[]);
    //console.log(data);
    const src= Object.keys(data);
    console.log("Hi",src);
  return (
    <ScrollView>
       <Appbar.Header>
            <Appbar.Content title="Plant a tree Initiative"/>
        </Appbar.Header>
        <IconButton
          icon="plus"
          color="crimson"
          size={30}
          onPress={() => setModalVisible(true)}
        />
      <View style={styles.centeredView}>
              {/*Modal Content Starts Here*/}
                <Modal
                  animationType="slide"
                  transparent={true}
                  visible={modalVisible}
                  >

                  <View style={styles.centeredView}>
                    <ScrollView style={styles.modalView}>
                      
                    <Appbar.Header style={{ padding:10}}>
                        <Appbar.Content title="Share your story.." />
                    </Appbar.Header>
                      <Card>
                        <Card.Content >
                          <View style={{marginLeft:0,marginRight:0,
                          }}>
                          <Card >
                         <Card.Content>
                          <TextInput
                            style={{}}
                            label="Your name...."   
                            mode="outlined"
                            value={name}
                            onChangeText={text =>{ setName(text)}} 
                          />
                          <TextInput
                            style={{}}
                            label="Story Title...."   
                            mode="outlined" 
                            value={title}
                            onChangeText={text =>{ setTitle(text)}}
                          />
                          <TextInput
                            style={styles.formcomponents}
                            label="Share your thoughts...."   
                            mode="outlined"
                            multiline={true}
                            numberOfLines={8}
                            value={description}
                            onChangeText={text =>{ setDescription(text)}}
                          
                          />
                          </Card.Content>
                          </Card>
                            </View>
                            <Card>                            
                                <Button mode="contained" style={{margin:20}} 
                                onPress={savePost}>
                                          post
                                </Button>
                                <Button mode="contained" style={{margin:20,backgroundColor:'crimson'}} onPress={() => setModalVisible(!modalVisible)}>
                                          close
                                </Button>
                            </Card>
                        </Card.Content>
                      </Card>
                    </ScrollView>
                  </View>
                </Modal>  
          </View>
    <View>
                  {/* DATA FROM FIREBASE  */}

                  <Text>{data?.description}</Text>
    </View>
  
    </ScrollView>
  )
}


  
const styles = StyleSheet.create({
  centeredView: {
      
    marginTop: 45,
    marginBottom:45,
  },

  modalView: {
    backgroundColor: "white",
    borderRadius: 20,
    
    marginTop:70,
    marginBottom:20,
    marginRight:20,
    marginLeft:20,
    shadowColor: "#000",
    shadowOffset: {
      width: 0,
      height: 2
    },
    shadowOpacity: 0.25,
    shadowRadius: 3.84,
    elevation: 5
    },
  openButton: {
    backgroundColor: "#F194FF",
    borderRadius: 20,
    padding: 10,
    elevation: 2
  },
  textStyle: {
    color: "white",
    fontWeight: "bold",
    textAlign: "center"
  },
});

Data Format:

Object {
  "-MQXpKu8Zh1PCVsBLquO": Object {
    "description": "Good story.",
    "id": 0.8842625745597491,
    "name": "Subhodeep",
    "title": "Story 1 ",
  },
  "-MQXpRXS5_6m6YTZ39e0": Object {
    "description": "Good story 2.",
    "id": 0.8767685757714464,
    "name": "Sanjoy",
    "title": "Story 2",
  },
  "-MQXpX7ku-41CreQ8SOP": Object {
    "description": "Good story 3.
",
    "id": 0.9976208307830834,
    "name": "Sanchari",
    "title": "Story 3",
  },

This is my data format

1 Answer 1

1

Since the data from Firebase consists of multiple nodes, you'll need to iterate over the results and map each child to a new component.

I typically find that easiest by first converting the snapshot to an array (instead of an Object) when it is loaded:

useEffect(()=>{
  const data = firebase.database().ref("posts");
  data.on("value", datasnap =>{
    let data = [];
    datasnap.forEach((childsnap) => {
      let val = childsnap.val();
      val["$key"] = childsnap.key;
      data.push(val);
    })
    setmyData(data);
  })
},[]);

Then in the rendering code we can loop over this data array and render a component for each item:

data.map((item) => <Text id={item["$key"]}>{item.description}</Text>)

There might be some syntax errors in the rendering, but the overall flow should be clear from this.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.