小能豆

Cloud Storage 中的图片未在 .map 列表中重新呈现

javascript

我正在从 Firebase Cloud Firestore 中提取 .map 中的帖子列表。我还有与每篇帖子相关的照片,我使用post.title + '.jpg'Cloud Storage 中的 来获取它们。帖子标题提取效果很好,但使用 时fetchImage它不会显示在帖子中。它显示在 console.log 中。我也可以从控制台访问 url,所以那里没有问题。

有任何想法吗?

{this.state.posts.map((post, i) => {
  let fetchImage
  firebase
  .storage()
  .ref(post.title + '.jpg')
  .getDownloadURL()
  .then((url) => {
    console.log(url)
    fetchImage = url;
  });
  return (
    <Text>{post.title}</Text>
    <Image
      style={styles.image}
      source={{
      uri: fetchImage
      }}
    />
  )}
)}

阅读 48

收藏
2024-06-16

共1个答案

小能豆

您遇到的问题是由于从 Firebase 存储中获取图像的异步特性造成的。getDownloadURL调用时,它会返回一个承诺,并且分配fetchImage = url在组件已经渲染之后发生。这就是在初始渲染期间fetchImage保留的原因。undefined

为了解决这个问题,您可以使用 React 状态来存储获取的 URL。获取 URL 后,您可以更新状态,从而触发使用更新后的图像 URL 重新渲染组件。

以下是实现此目的的方法:

  1. 异步获取帖子和图像 URL。
  2. 将图像 URL 存储在组件状态中。

这是您的代码的更新版本:

import React, { useState, useEffect } from 'react';
import { View, Text, Image, StyleSheet } from 'react-native';
import firebase from 'firebase/app';
import 'firebase/storage';
import 'firebase/firestore';

const MyComponent = () => {
  const [posts, setPosts] = useState([]);
  const [imageUrls, setImageUrls] = useState({});

  useEffect(() => {
    const fetchPosts = async () => {
      const postsSnapshot = await firebase.firestore().collection('posts').get();
      const postsData = postsSnapshot.docs.map(doc => doc.data());
      setPosts(postsData);

      const urls = {};
      for (const post of postsData) {
        const url = await firebase.storage().ref(post.title + '.jpg').getDownloadURL();
        urls[post.title] = url;
      }
      setImageUrls(urls);
    };

    fetchPosts();
  }, []);

  return (
    <View>
      {posts.map((post, i) => (
        <View key={i}>
          <Text>{post.title}</Text>
          {imageUrls[post.title] && (
            <Image
              style={styles.image}
              source={{ uri: imageUrls[post.title] }}
            />
          )}
        </View>
      ))}
    </View>
  );
};

const styles = StyleSheet.create({
  image: {
    width: 100,
    height: 100,
  },
});

export default MyComponent;

解释:

  1. 状态初始化
  2. posts:存储从 Firestore 获取的帖子列表。
  3. imageUrls:存储帖子标题到其各自图像 URL 的映射。
  4. 获取数据
  5. useEffect钩子中,从 Firestore 获取帖子。
  6. 一旦获取到帖子,就对其进行迭代以获取图像 URL。
  7. 将图像 URL 存储在imageUrls状态中。
  8. 渲染
  9. 映射posts状态来呈现每个帖子。
  10. 使用帖子标题检查图像 URL 在该imageUrls州是否可用。
  11. 如果图像 URL 可用,则Image使用该 URL 渲染组件。

这种方法可确保组件在获取的图像 URL 可用时重新渲染,从而正确显示图像。

2024-06-16