从 Firebase 存储调用图像 - 无效的钩子调用。 Hooks 只能在函数组件的主体内部调用
Posted
技术标签:
【中文标题】从 Firebase 存储调用图像 - 无效的钩子调用。 Hooks 只能在函数组件的主体内部调用【英文标题】:Calling images from firebase storage - Invalid hook call. Hooks can only be called inside of the body of a function component 【发布时间】:2021-12-26 02:46:05 【问题描述】:大家好!
我正在尝试制作一个自定义挂钩,可用于从 Firebase 存储中调用图像。函数的输入来自包含 JSON 的 DATA.js 文件。例如 useImageSource(item.photo) - item.photo 将等于“lowerbody/forward-legswing”(这是我的 Firebase 存储中该锻炼图像的文件结构)。希望当我向您展示我的代码时它更有意义!哈!
使用ImageSource
以下是我为此制作的自定义钩子的示例:
import React, useState, useEffect from "react";
import firebase from "@react-native-firebase/app";
import "@react-native-firebase/storage";
import FastImage from "react-native-fast-image";
import getIllustration, Images from "@flexeee:assets/images/Images";
export default function useImageSource(image, defaultImage)
const storage = firebase.storage();
const [imageSource, setImageSource] = useState();
useEffect(() =>
async function getImageSource()
try
const url = await storage.ref(`images/$image.png`).getDownloadURL();
setImageSource(
uri: url,
priority: FastImage.priority.normal,
);
catch (err)
setImageSource(defaultImage ?? Images.upperBody);
getImageSource();
, [image, defaultImage, storage]);
return imageSource;
子类别
所以这里是我尝试实现这个 useImageSource 钩子的地方的例子:
import React, useState from "react";
import
StyleSheet,
Text,
View,
FlatList,
TouchableOpacity,
Image,
Dimensions,
from "react-native";
import Fontisto from "@expo/vector-icons";
import ReactNativeHapticFeedback from "react-native-haptic-feedback";
import useImageSource from "@flexeee:common/utils/hooks/useImageSource";
import Colors from "@flexeee:common/theme/Colors";
import Fonts from "@flexeee:common/theme/Sizes";
import Images from "@flexeee:assets/images/Images";
const width, height = Dimensions.get("window");
const options =
enableVibrateFallback: true,
ignoreandroidSystemSettings: false,
;
export default function SubCategories( navigation, workouts, category )
const renderItem = ( item ) =>
const imageSrc = useImageSource(item.photo, Images.upperBody);
return (
<TouchableOpacity
style= marginBottom: 10 * 2
onPress=() =>
navigation.navigate("DetailStack",
screen: "WorkoutDetails",
params: item: item ,
) & ReactNativeHapticFeedback.trigger("impactLight", options)
>
/* Image */
<View style=styles.workoutImageContainer>
item.isLocked ? (
<View style= backgroundColor: Colors.black, borderRadius: 10 >
<Image
source=imageSrc
resizeMode="cover"
style=styles.workoutImage
opacity=0.75
/>
</View>
) : (
<Image
source=imageSrc
resizeMode="cover"
style=styles.workoutImage
/>
)
<View style=styles.durationContainer>
<Text style=styles.title>item.duration</Text>
</View>
</View>
item.isLocked && (
<View style=styles.lockContainer>
<Fontisto name="locked" size=28 color=Colors.white />
</View>
)
<View style=styles.subtitleContainer>
<Text style=styles.subtitle>item.name</Text>
</View>
</TouchableOpacity>
);
;
return (
<View>
<View style=styles.headingContainer>
<Text style=styles.heading>category.name</Text>
<TouchableOpacity
onPress=() =>
navigation.navigate("DetailStack",
screen: "WorkoutList",
params: category: category, workouts: workouts ,
) & ReactNativeHapticFeedback.trigger("impactLight", options)
>
<Text style=styles.viewOption>View all</Text>
</TouchableOpacity>
</View>
<FlatList
data=workouts
horizontal
keyExtractor=(item) => `$item.id`
renderItem=renderItem
contentContainerStyle=
showsHorizontalScrollIndicator=false
/>
</View>
);
DATA.js
这是我的数据的一些上下文(示例)
export const workoutData = [
id: 1,
name: "Lower-body warm up",
rating: 4.8,
categories: [1],
isLocked: false,
description: `Ah, the infamous 'leg day.' Sometimes it's a struggle to even make it to the gym when you're planning to train your lower body, let alone spend time warming up before the often dreaded workout. But not only can avoiding a warm-up increase your risk of injury, it can also hinder your performance. This holds especially true when you walk into the gym after a night of sleep or a long day of sitting at a desk. A good warm-up will raise your body temperature, improve mobility and groove proper movement patterns. Some people require more mobility, while others require more stability. Regardless of your needs, there are several warm-up exercises that can prepare you for almost any type of lower-body exercise.\n \nTip: Spend five minutes on a foam roller before your warm-up to better prepare your muscles.`,
photo: "lowerbody/deep-squat",
duration: `5 mins`,
trainer:
avatar: "lowerbody/deep-squat",
name: "Amy",
,
workout: [
exerciseId: 1,
name: "Forward Leg Swing (left)",
photo: "lowerbody/forward-legswing",
description:
"Stand straight with your feet hip-width apart and hold onto a wall. Keeping one leg stationary, slowly swing the opposite leg forward and backward in a single smooth movement.",
muscle: "Hip flexors, hamstrings, quadriceps, glutes & calves",
duration: 30,
,
exerciseId: 2,
name: "Forward Leg Swing (right)",
photo: "lowerbody/forward-legswing",
description:
"Stand straight with your feet hip-width apart and hold onto a wall. Keeping one leg stationary, slowly swing the opposite leg forward and backward in a single smooth movement.",
muscle: "Hip flexors, hamstrings, quadriceps, glutes & calves",
duration: 30,
,
Firebase 存储文件结构
希望这些信息足以帮助我解决这个问题吗?如果不是,我很乐意提供更多详细信息 - 需要注意的是,在此之前,当我在 DATA.js 文件中本地调用我的文件时正在工作。只是需要一些想法或帮助来说明为什么这不起作用!
感谢您抽出宝贵时间,期待收到回复!
【问题讨论】:
【参考方案1】:好的,看来我的问题是我没有在渲染中返回任何内容。我必须返回另一个我称为 companyImage 的组件,该组件在渲染中返回快速图像,称为 FastImage 并将图像作为道具。
希望这对阅读本文的人有用!
【讨论】:
以上是关于从 Firebase 存储调用图像 - 无效的钩子调用。 Hooks 只能在函数组件的主体内部调用的主要内容,如果未能解决你的问题,请参考以下文章
Firebase 存储:字符串与格式“base64”不匹配:发现无效字符
文件上传到 Firebase 存储不起作用(“存储/无效参数”)
React - 错误:无效的钩子调用。 Hooks 只能在函数组件的主体内部调用