0

Using react hooks with firebase real time database with a project Im working on for the first time, the data is being retrieved and logs in the console. BUT I am unable go move out side the useEffect function to display values on the screen! Would really appreciate some help!

videoArray needs to be put in a FlatList, as you can see in the code bellow videoArray logs values in the console in useEffect function. However, once I move out that function to add it into a FlatList it is null because the values are in a local function.

My question is, how am I able to pass value of videoArray (in useEffect) into the FlatList?

import React, { useState, useEffect } from 'react'
import { FlatList, View, TouchableOpacity, Text, StyleSheet, SafeAreaView } from 'react-native';
import { Center } from '../components/Center'
import { Video } from 'expo-av';
import firebase from '../firebase'
const videoRef = firebase.database().ref('videoCollaction');

export const FeedScreen = ({ }) => {

    let [videoArray, setVideo] = useState([]);


    useEffect(() => {

        videoRef.on('value', (childSnapshot) => {
             videoArray = [];
            childSnapshot.forEach((doc) => {
                videoArray.push({
                    key: doc.key,
                    video: doc.toJSON().video,
                });
            })    
        })

        // able to log values only here 
        console.log('working:', videoArray); 

    });

        // get video uri from firebase (testing)
        // readVideo = () => {
            // var collection = firebase.database().ref("videoCollactionvideo" + "/video").orderByValue();
            // console.log('uri', collection); 
        // }



    return (
        <SafeAreaView>
            <Text>Feed Screen</Text>

            {/* null here: need values to show up here*/}
            {console.log(" test",videoArray)}

            <FlatList
                data={videoArray}
                renderItem={({ item, index }) => {
                    return (
                        <View>

                            <Text style={{ fontSize: 35, color: 'red' }}>Video:...</Text>


                            <TouchableOpacity onPress={() => console.log('pressed')}><Text style={{ color: 'blue' }}>Expand</Text></TouchableOpacity>
                        </View>
                    );
                }} keyExtractor={({ item }, index) => index.toString()}>
            </FlatList>

        </SafeAreaView>
    );
}
0

3 Answers 3

2

Try this:

  useEffect(() => {
    const temp = []; // temp array
    videoRef.on("value", childSnapshot => {
      childSnapshot.forEach(doc => {
        temp.push({
          key: doc.key,
          video: doc.toJSON().video
        });
      });
      setVideo(temp); // update state array
    });
  }, []);
Sign up to request clarification or add additional context in comments.

1 Comment

one other thing :) I'm not 100% sure how it is intended to work, but the way you declared temp - it will be getting results in addition while keeping old values that already were there. If you declare it within .on callback - then trigger from firebase will override list completely
2

It seems like you are trying to update the State Hook (videoArray), but you are doing it the wrong way (it shouldn't be modified directly). Instead, use the setVideo update method which you created with the Hook (let [videoArray, setVideo] = useState([]);):

useEffect(() => {
    videoRef.on('value', (childSnapshot) => {
        newVideoArray = [];
        childSnapshot.forEach((doc) => {
            newVideoArray.push({
                key: doc.key,
                video: doc.toJSON().video,
            });
        })    
    })

    // able to log values only here 
    console.log('working:', newVideoArray); 
    setVideo(newVideoArray);
});

Check out Using the Effect Hook for more information on how to use this specific hook (the Optimizing Performance by Skipping Effects section might be especially of interest).

In essence, this functionality is similar to your Functional Component's stateful counterparts (React.Component or React.PureComponent), where:

Constructor is the only place where you should assign this.state directly. In all other methods, you need to use this.setState() instead.

Comments

2

Try this:

import React, { useState, useEffect } from 'react'
import { FlatList, View, TouchableOpacity, Text, StyleSheet, SafeAreaView } from 'react-native';
import { Center } from '../components/Center'
import { Video } from 'expo-av';
import firebase from '../firebase'
const videoRef = firebase.database().ref('videoCollaction');


export const FeedScreen = ({ }) => {
    let [videoArray, setVideoArray] = useState([]);


    useEffect(() => {

        videoRef.on('value', (childSnapshot) => {
            const newVideoArray = [];
            childSnapshot.forEach((doc) => {
                newVideoArray.push({
                    key: doc.key,
                    video: doc.toJSON().video,
                });
            })    
            setVideoArray(newVideoArray);
        })

        // able to log values only here 
        console.log('working:', videoArray); 

    }, []);


    console.log('State also working :) >> ', videoArray); 


    return (
        <SafeAreaView>
            <Text>Feed Screen</Text>

            {/* null here: need values to show up here*/}
            {console.log(" test",videoArray)}

            <FlatList
                data={videoArray}
                renderItem={({ item, index }) => {
                    return (
                        <View>

                            <Text style={{ fontSize: 35, color: 'red' }}>Video:...</Text>


                            <TouchableOpacity onPress={() => console.log('pressed')}><Text style={{ color: 'blue' }}>Expand</Text></TouchableOpacity>
                        </View>
                    );
                }} keyExtractor={({ item }, index) => index.toString()}>
            </FlatList>

        </SafeAreaView>
    );
}

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.