【问题标题】:Fetch image based on text and display from API react基于文本获取图像并从 API react 显示
【发布时间】:2020-10-12 14:52:38
【问题描述】:

我使用 API 检索了一个类别列表。现在我想根据类别从 URL 中获取图像。我尝试使用每个类别从另一个 API 获取图像,但我不知道该怎么做。

import React, { useEffect, useState } from 'react';
import './css/Category.css';

function Category() {

    useEffect(() => {
        fetchData();
        getImage();
    }, []);

    const [categories, setCategories] = useState([]);
    const [image, setImage] = useState('');

    const fetchData = async () => {
        const data = await fetch('https://opentdb.com/api_category.php')
        const categories = await data.json();
        console.log(categories.trivia_categories)
        setCategories(categories.trivia_categories)
    }

    const getImage = async (name) => {
        console.log(name)
        const q = name.split(' ').join('+')
        const img = await fetch(`https://pixabay.com/api/?key=apikey&q=${q}&image_type=photo`)
        const image = await img.json();
        console.log(image)
        setImage(image.previewURL)

    }
    return (
        <div className="categories">
            Yesss
            <div className="category-grid">
                {categories.map(category => (
                    <div className="category">
                        {category.name}
                        <img src={getImage(category.name)} /> //do not know what to do here to fetch image of the respective category 
                    </div>
                ))}
            </div>


        </div>
    )
}

export default Category;

在 Noah 建议的更改后,我只能显示一张图片。

const getImage = async (name) => {
        const query = stringMan(name.name)
        console.log(query)
        const img = await fetch(`https://pixabay.com/api/?key=17160673-fd37d255ded620179ba954ce0&q=${query}&image_type=photo`)
        const image = await img.json();
        console.log(image)
        setImage({ [name.name]: image.hits[0].largeImageURL })
    }
return (
        <div className="categories">
            Yesss
            <div className="category-grid">
                {categories.map(category => (
                    <div className="category" key={category.id}>
                        {category.name}
                        <img key={category.id} src={image[category.name]} />
                    </div>
                ))}
            </div>
        </div>
    )

【问题讨论】:

    标签: reactjs api react-router react-hooks


    【解决方案1】:

    您可以在此处进行一些更改。

    我看到的一个问题是您有一个 image 变量,该变量被重新用于每个类别。因此,当您映射类别列表时(例如,假设我们有类别:[historysciencemath])。当前代码将调用getImage 3次,参数为historysciencemath

    但是,只有 一个 状态变量被写入。这意味着 setImage 的最后一次执行是唯一会被保留的。

    因此,您可能希望将 image 从类别图像的 URL 更改为具有以下形状的对象:

    {
       history: [url],
       science: [url],
       math: [url]
    }
    

    要进行的另一个更改是您在渲染输出&lt;img src={getImage(category.name)} /&gt; 中直接调用getImage() 函数。相反,这应该简单地使用分配给图像状态的值:&lt;img src={image} /&gt;

    要真正获取图像,您可以使用useEffect 挂钩(https://reactjs.org/docs/hooks-effect.html) 来响应对类别变量的更改。这可能看起来像:

    useEffect(() => {
       categories.forEach((c) => getImage(c));
    }, [categories]);
    

    每当依赖关系发生变化时,useEffect 钩子都会调用它给出的函数。这将允许您触发getImage 函数以响应对类别的更改。

    【讨论】:

    • 所以如果我将图像状态设为键值对,我将如何访问 img 标签内的 url?
    • 它可能看起来像:&lt;img src={images[category.name]} /&gt; 假设 images 是保存类别到图像名称映射的变量的名称。
    • 好的,我试过了,但它只显示一张图像。我不明白为什么
    • 我已经添加了问题中的更改,您可以检查并告诉我这里有什么问题吗?哦,stringMan() 函数建议在类别名称中添加 + 而不是空格,因为 API 接受这样的多词类别。
    【解决方案2】:

    正如上面/下面的@noah-callaway 所述,可以进行很多改进,但直截了当,您需要简单地修复URI 创建逻辑以使用encodeURIComponent,如下所示:

    import React, { useEffect, useState } from 'react';
    
    function Category() {
    
    useEffect(() => {
        fetchData();
        getImage();
    }, []);
    
    const [categories, setCategories] = useState([]);
    const [image, setImage] = useState('');
    
    const fetchData = async () => {
        const data = await fetch('https://opentdb.com/api_category.php')
        const categories = await data.json();
        console.log(categories.trivia_categories)
        setCategories(categories.trivia_categories)
    }
    
    const getImage = async (name) => {
        return encodeURI(`https://pixabay.com/api/?key=apikey&q=${encodeURIComponent(name)}&image_type=photo`)
    }
    return (
        <div className="categories">
            Yesss
            <div className="category-grid">
                {categories.map(category => (
                    <div className="category">
                        {category.name}
                        <img src={getImage(category.name)} />
                    </div>
                ))}
            </div>
    
    
        </div>
    )
    }
    

    没有 api 密钥,所以无法测试,但它会给你类似的东西

    https://pixabay.com/api/?key=apikey&q=Entertainment%3A%20Comics&image_type=photo
    

    祝你好运,希望它有效。

    【讨论】:

    • 但 API 不支持该 URL
    猜你喜欢
    • 2021-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-04
    • 2020-10-10
    • 2020-11-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多