加载 Firebase 图像的自定义挂钩 URL
Custom Hook to Load Firebase Image URL
我正在尝试创建一个自定义挂钩,该挂钩将为存储在 Firebase 中的图像加载 URL。
到目前为止,我已经得出以下结论:
useLoadImageURL.js
export default async function useLoadImageURL(projectId, fileName) {
const [url, setURL] = useState()
useEffect(() => {
return url
}, [url])
const storage = getStorage(app);
setURL(await getDownloadURL(ref(storage, `images/projects/${projectId}/${fileName}`)))
}
然而,当我在我的组件中使用它时,我只得到承诺,因此使用返回的承诺作为 URL 不起作用。
我通过以下方式调用挂钩:
ProjectCard.js
export default function ProjectCard({ project }) {
const coverImageURL = useLoadImageURL(project.id, project.coverImagePath)
return <img src={coverImageURL} />
}
如何更改挂钩或如何调用它来检索实际 URL?
您可以从您的代码中删除 async
和 await
,而不是在挂钩的底部调用 setUrl
——这将在每次被调用者组件时启动调用重新呈现——将其包装在 useEffect
中,并在 then
回调中更新状态。
编辑:完整代码:
const storage = getStorage(app); // as app seems to be external to the hook, storage can likely be too
export default function useLoadImageURL(projectId, fileName) {
const [url, setUrl] = useState();
useEffect(() => {
getDownloadURL(ref(storage, `images/projects/${projectId}/${fileName}`))
.then((value) => {
setUrl(value); // should work provided getDownloadURL actually is a promise that gives a string
});
}, [projectId,fileName]);
return url;
}
这将使 url
状态仅在 projectId
或 fileName
更改时更改。
您必须在 useEffect
挂钩内执行副作用逻辑(在您的情况下等待异步响应)。
根据您的意图,使用 promises 和 async
await
,您的代码片段挂钩应该是这样的。
import { useState, useEffect } from "react";
// hook
function useLoadImageURL(filename) {
const [url, setURL] = useState("some-image-spinner-url");
// simulating your async api call to firebase service
const setTimeoutAsync = (cb, delay) =>
new Promise((resolve) => {
setTimeout(() => {
resolve(cb());
}, delay);
});
useEffect(() => {
async function asyncFn() {
const url = await setTimeoutAsync(() => filename, 3000);
setURL(url);
}
asyncFn();
}, [filename]);
return [url];
}
// main component
function App() {
const [url] = useLoadImageURL("firebase-file-name-f1");
return <div> {url} </div>;
}
export default App;
我正在尝试创建一个自定义挂钩,该挂钩将为存储在 Firebase 中的图像加载 URL。
到目前为止,我已经得出以下结论:
useLoadImageURL.js
export default async function useLoadImageURL(projectId, fileName) {
const [url, setURL] = useState()
useEffect(() => {
return url
}, [url])
const storage = getStorage(app);
setURL(await getDownloadURL(ref(storage, `images/projects/${projectId}/${fileName}`)))
}
然而,当我在我的组件中使用它时,我只得到承诺,因此使用返回的承诺作为 URL 不起作用。
我通过以下方式调用挂钩:
ProjectCard.js
export default function ProjectCard({ project }) {
const coverImageURL = useLoadImageURL(project.id, project.coverImagePath)
return <img src={coverImageURL} />
}
如何更改挂钩或如何调用它来检索实际 URL?
您可以从您的代码中删除 async
和 await
,而不是在挂钩的底部调用 setUrl
——这将在每次被调用者组件时启动调用重新呈现——将其包装在 useEffect
中,并在 then
回调中更新状态。
编辑:完整代码:
const storage = getStorage(app); // as app seems to be external to the hook, storage can likely be too
export default function useLoadImageURL(projectId, fileName) {
const [url, setUrl] = useState();
useEffect(() => {
getDownloadURL(ref(storage, `images/projects/${projectId}/${fileName}`))
.then((value) => {
setUrl(value); // should work provided getDownloadURL actually is a promise that gives a string
});
}, [projectId,fileName]);
return url;
}
这将使 url
状态仅在 projectId
或 fileName
更改时更改。
您必须在 useEffect
挂钩内执行副作用逻辑(在您的情况下等待异步响应)。
根据您的意图,使用 promises 和 async
await
,您的代码片段挂钩应该是这样的。
import { useState, useEffect } from "react";
// hook
function useLoadImageURL(filename) {
const [url, setURL] = useState("some-image-spinner-url");
// simulating your async api call to firebase service
const setTimeoutAsync = (cb, delay) =>
new Promise((resolve) => {
setTimeout(() => {
resolve(cb());
}, delay);
});
useEffect(() => {
async function asyncFn() {
const url = await setTimeoutAsync(() => filename, 3000);
setURL(url);
}
asyncFn();
}, [filename]);
return [url];
}
// main component
function App() {
const [url] = useLoadImageURL("firebase-file-name-f1");
return <div> {url} </div>;
}
export default App;