我从firebase存储中获取视频,现在在应用程序中显示它们。我有3个视频和问题是,每次我渲染屏幕上只有一个视频渲染。UseState
为setVideoUrl
分配随机数量的视频URL。有时videoUrls
只包含一个视频,而其他时候有2个。我不明白为什么会这样。useEffect也被多次调用。有人能帮忙吗?
这是代码:
import React from "react";
import firebaseConfig from "../../../firebaseConfig";
import { View, Text, StyleSheet, Dimensions } from "react-native";
import { useEffect, useState } from "react";
import {getStorage, ref, listAll, getDownloadURL } from "firebase/storage"
import { Video } from "expo-av";
// import { WebView } from 'react-native-webview';
import { ActivityIndicator } from "react-native";
// import VideoPlayer from 'react-native-video';
const Program1 = () => {
const [videoUrls, setVideoUrls] = useState([]);
// const { width, height } = Dimensions.get("window");
const [loading, setLoading] = useState(true);
useEffect(() => {
FetchVideos();
}, []);
const FetchVideos = () => {
const storage = getStorage();
const listRef = ref(storage, "PersonligUtveckling/videos/");
listAll(listRef)
.then((res) => {
const urls = [];
res.items.forEach((itemRef) => {
getDownloadURL(itemRef)
.then((url) => {
console.log('URL of video file:', url);
urls.push(url);
setVideoUrls(urls);
setLoading(false);
})
});
})
.catch((error) => {
console.log(error);
});
}
const handleVideoError = (error) => {
console.log("Video error:", error);
};
const handleVideoLoad = () => {
console.log("Video loaded");
};
console.log(videoUrls.length);
if (loading) {
return (
<View style={[styles.container, styles.horizontal]}>
<ActivityIndicator size="large" />
{ loading && videoUrls.length === 0 ? <Text>No videos found</Text> : <ActivityIndicator size="large" />}
</View>
);
}
return (
<View style={styles.container}>
<Text>Hello</Text>
{!loading ?
videoUrls.map((url, index) => (
<Video
key={index}
isMuted={false}
volume={2.0}
source={{ uri: url }}
style={styles.video}
useNativeControls={true}
resizeMode="contain"
onError={handleVideoError}
onLoad={handleVideoLoad}
/>
)) : <ActivityIndicator size="large" />}
</View>
);
};
const styles = StyleSheet.create({
container: {
paddingTop: 40,
alignItems: 'center',
},
video: {
width: 320,
height: 240,
marginBottom: 20,
},
});
export default Program1;
控制台日志:
URL of video file: https://firebasestorage.googleapis.com/v0/b/phantoms-mobile-app.appspot.com/o/PersonligUtveckling%2Fvideos%2Fvideo1.mp4?alt=media&token=a4bbedc2-bd17-428d-9bf4-267143af84fc
LOG 1
LOG 1
LOG URL of video file: https://firebasestorage.googleapis.com/v0/b/phantoms-mobile-app.appspot.com/o/PersonligUtveckling%2Fvideos%2Fvideo.mp4?alt=media&token=d2449d1f-7f03-481f-a1ca-989ba55cd243
LOG 2
LOG URL of video file: https://firebasestorage.googleapis.com/v0/b/phantoms-mobile-app.appspot.com/o/PersonligUtveckling%2Fvideos%2Fvideo2.mp4?alt=media&token=491ec16c-6994-45fb-9b76-40f575fa6df1
LOG Video loaded
2条答案
按热度按时间lsmepo6l1#
您没有正确处理此任务的异步特性。您需要等待所有请求都完成,然后才能将它们设置为状态。否则会导致
urls
阵列出现争用条件。但这个数组不需要存在。你需要把所有的东西都保存在Promise链中。vmdwslir2#
问题似乎是由获取视频URL的异步性质引起的。您使用forEach循环遍历这些项,并且对于每个项,您调用异步函数getDownloadURL()。这可能导致setVideoUrls()函数以不可预测的顺序被调用多次。
要修复此问题,可以使用Promise.all()确保在更新状态之前获取所有下载URL。此外,确保在useEffect()中使用依赖数组,以防止多次调用它。