【问题标题】:How Do You Resolve Promises for Attributes of HTML Tags?你如何解决 HTML 标签属性的承诺?
【发布时间】:2021-05-17 03:05:50
【问题描述】:

我正在尝试使用 React、GraphQL、Apollo、MongoDB 和 Express 制作一个“最喜欢的专辑”应用程序。 我在实现一个从查询 MusicBrainz API 的 localhost 服务器自动获取封面艺术的功能时遇到了麻烦。到目前为止,艺术获取方面完美运行:如果我输入艺术家 + 专辑组合,我会得到封面艺术并将专辑返回给客户端。

我的理想流程是这样的:

  • 应用加载时,从 MongoDB 中获取专辑数据。
  • 如果专辑有 thumbnail 属性(封面艺术的 URL),
    • 使用缩略图并显示图像。
  • 否则,
    • 去取封面。
    • 承诺履行后显示图像。

问题是,getAlbumCover(album) 总是 返回一个承诺,就像 async 函数似乎做的那样。我只是不确定我必须做什么才能让它从 fetch 操作中返回 URL。任何帮助将不胜感激。

下面是Album 组件的代码。

import { useState } from 'react';

const Album = (props) => {

    const getAlbumCover = async (album) => {
        // Slugify text:
        function convertToSlug(Text) {
            return Text
                .toLowerCase()
                .replace(/ /g, '-')
                .replace(/\//g, '-')
                .replace(/[^\w-]+/g, '')
                ;
        }
        const artist = convertToSlug(album.artist.name);
        const name = convertToSlug(album.name);
        var result = await fetch(`http://localhost:5000/album-art/${artist}/${name}`, {
            method: 'get',
            headers: {
                'Accept': 'application/json'
            }
        })
            .then(res => res.json())
            .then((result) => {
                return (<img id={`img-${album.id}`} src={result} />);
            })
    }
    
    const album = props.album;
    return (
        <div className="album-container">
            <img id={`img-${album.id}`} src={album.thumbnail ? album.thumbnail : getAlbumCover(album)} />
            <div className="album-header">
                <h3><em>{album.name}</em> <span className="details-yor">({album.yearOfRelease})</span></h3>
                <h3>- {album.artist.name}</h3>
            </div>
        </div>
    )
}

export default Album;

【问题讨论】:

    标签: reactjs asynchronous async-await promise fetch


    【解决方案1】:

    如果需要取回封面,则置入状态:

    const Album = (props) => {
        const [cover, setCover] = useState('');
    

    如果需要,在组件安装时获取封面:

    useEffect(() => {
        if (!props.album.thumbnail) {
            getAlbumCover();
        }
    }, []);
    
    // inside getAlbumCover:
    .then(res => res.json())
    .then(setCover)
    .catch(handleError); // don't forget this; unhandled rejections should always be avoided
    

    然后渲染它:

    <img id={`img-${album.id}`} src={album.thumbnail || cover} />
    

    【讨论】:

    • 非常感谢您的帮助!这完美地解决了它。我曾多次尝试使用状态,但由于重新渲染次数过多,我不断收到错误。我考虑过 useEffect 但不知道在这种情况下我将如何实现它。再次感谢您!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-24
    • 2016-12-23
    • 1970-01-01
    相关资源
    最近更新 更多