如何使用 Edamam API 中的 NextURL 加载下一组 api 结果

问题描述 投票:0回答:1

https://github.com/jhconger/FindYourRecipe

Edamam API 一次仅返回 20 个结果。 我想使用“下一个”按钮加载下一组 20 个结果,然后可以选择使用“上一个”按钮返回到上一个结果。我尝试了许多不同的方法来实现这一目标,并进行了大量的搜索来寻找解决方案。 有人能引导我走向正确的方向吗?这是我的一些代码以及存储库的链接:

使用ReactJS 编辑:此代码将允许我在每次更改查询时获取、返回和显示下一组 20 个结果,以及返回到前 20 个结果。 然而,我一直无法弄清楚如何获取结果 41-60 等。我确信我正在错误地处理这个问题,所以任何帮助将不胜感激。

import logo from './logo.svg';
import './App.css';
import styled from 'styled-components'
import 'bootstrap/dist/css/bootstrap.min.css';
import {Navbar, Container, Nav, Form, FormControl, Button} from 'react-bootstrap';
import RecipeBox from './RecipeBox';
import React, {useEffect, useState} from 'react';
import ReactLoading from "react-loading";
import LoadingScreen from "./LoadingScreen";

const AppIcon = styled.img`
display: flex;
flex-direction: row;
align-items: center;
height: 75px;
width: 75px;
`;

const App =()=> {

    const APP_ID = "2d320d45";
    const APP_KEY = "07015b8fb7809a5ee4afdbe546b5d4b7";
    const [recipes, setRecipes] = useState ([]);
    const [next, setNext] = useState ([]);
    const [nextRecipes, setNextRecipes] = useState ([]);
    const [search, setSearch] = useState('');
    const [query, setQuery] = useState("chicken")

    useEffect(() => {
        getRecipes()
    }, [query, next]);

    useEffect(() => {
        getNext()
    }, []);

    useEffect(() => {
        getNextRecipes()
    }, []);

    const getRecipes = async () => {
        const response = await fetch(`https://api.edamam.com/api/recipes/v2?type=public&q=${query}&app_id=${APP_ID}&app_key=${APP_KEY}`)
        const data = await response.json();
        setNext(data._links.next.href)
        setRecipes(data.hits);
        console.log(next);
        getNextRecipes();
    };

    const getNext = async () => {
        const response = await fetch(response)
        console.log(response)
        const data = await response.json();
        console.log(data.hits)
        setNext(data._links.next.href)
        setNextRecipes(data.hits);
    };

    const getNextRecipes = async () => {
        const response = await fetch(next)
        console.log(response)
        const data = await response.json();
        console.log(data.hits)
        setNextRecipes(data.hits);
    };

    const updateSearch = e =>{
        setSearch(e.target.value)
    };

    const updateNext = e =>{
        setNext(e.target.value)
    };

    const updateRecipes = e =>{
        setRecipes(nextRecipes)
    };

    const getSearch = e => {
    e.preventDefault();
    setQuery(search)
        setSearch('');
    };

    const [loading, setLoading] = useState(true)
    useEffect(() => {
        setTimeout(() => setLoading(false), 6000)
    }, [])

    return (
        <>
            <Navbar bg="black" expand="lg" variant="dark">
                <Container fluid>
                    <AppIcon src='/RecipeLogo.svg'/>
                    <Navbar.Brand href="/home">Recipes for the Ages</Navbar.Brand>
                    <Navbar.Toggle className="navbar-toggle" aria-controls="navbarScroll"></Navbar.Toggle>
                    <Navbar.Collapse className="navbar-collapse" id="navbarScroll">
                        <Nav className="me-auto my-2 my-lg-3" style={{maxHeight:'100px'}} navbarScroll>

                        </Nav>
                        <Form onSubmit={getSearch} className="d-flex">
                            <FormControl type="search" placeholder="Search Recipes" className="me-2" value={search} onChange={updateSearch} aria-label="search"></FormControl>
                            <Button className="search-btn" variant="secondary" type="submit">
                                <h5>Search</h5>
                            </Button>
                        </Form>
                    </Navbar.Collapse>

                </Container>
            </Navbar>
            {recipes.length > 0 ?(
                <section className="hero">
            <div className= "container">
                <div className="grid">
                    {recipes.map(recipe =>(
                        <RecipeBox
                        key = {recipe._links.self}
                        title ={recipe.recipe.label}
                        image ={recipe.recipe.image}
                        calories ={recipe.recipe.calories}
                        ingredients ={recipe.recipe.ingredients}
                        link ={recipe.recipe.url}
                        ingredients={recipe.recipe.ingredients}
                        source={recipe.recipe.source}
                        healthLabels={recipe.recipe.healthLabels}
                        servings={recipe.recipe.yield}
                        />
                    ))}
                </div>
                <div className="d-flex justify-content-between">
                    <Button className="prev-btn" variant="secondary"  onClick={getRecipes}type="submit" >Previous</Button>
                    <Button className="next-btn" variant="secondary"  onClick={updateRecipes} type="submit">Next</Button>
                </div>

            </div>

                </section>

            ):(
                    <h2>Sorry !! No Recipes Found</h2>
                )}
        </>
  );
}

export default App;

编辑:我通过恢复到 API 的 V1 解决了这个问题,代码如下:

import logo from './logo.svg';
import './App.css';
import styled from 'styled-components'
import 'bootstrap/dist/css/bootstrap.min.css';
import {Navbar, Container, Nav, Form, FormControl, Button} from 'react-bootstrap';
import RecipeBox from './RecipeBox';
import React, {useEffect, useState, useRef} from 'react';
import ReactLoading from "react-loading";
import LoadingScreen from "./LoadingScreen";
import axios from 'axios';

const AppIcon = styled.img`
display: flex;
flex-direction: row;
align-items: center;
height: 75px;
width: 75px;
`;

const App = () => {
    const APP_ID = process.env.REACT_APP_API_ID;
    const APP_KEY = process.env.REACT_APP_API_KEY;
    const [recipes, setRecipes] = useState([]);
    const [currentPage, setCurrentPage] = useState(1);
    const [search, setSearch] = useState('');
    const [query, setQuery] = useState("chicken")
    const [pagination, setPagination] = useState(0);
    const [currentPagination, setCurrentPagination] = useState(0);
    const [page, setPage] = useState(1);
    const prevSearchIdRef = useRef();

    useEffect(() => {
        prevSearchIdRef.current = query;
    });

    const prevSearch = prevSearchIdRef.current
    const fetchRecipes = async () => {
        if (prevSearch !== query) {

        }

        const response = await fetch(`https://api.edamam.com/search?q=${query}&app_id=${APP_ID}&app_key=${APP_KEY}&from=${currentPagination}&to=${pagination + 20}`)
        const data = await response.json();
        console.log(response);
        setRecipes(data.hits);
        console.log(currentPagination);
    };

    const updateSearch = e => {
        setSearch(e.target.value);
    };

    const getSearch = e => {
        e.preventDefault();
        setQuery(search);
        setSearch('');
    };

    const prevClick = () => {
        if (pagination === 0) {
            return;
        }
        ;
        setPagination(pagination - 20);
        setCurrentPagination(currentPagination - 20);
        console.log(pagination);
    };

    const nextClick = () => {
        setPagination(pagination + 20);
        setCurrentPage(+1);
        setCurrentPagination(currentPagination + 20);
        console.log(pagination);
    };

    useEffect(() => {
        fetchRecipes();
    }, [query, pagination]);

    return (
        <>
            <Navbar bg="black" expand="lg" variant="dark">
                <Container fluid>
                    <AppIcon src='/RecipeLogo.svg'/>
                    <Navbar.Brand href="/home">Recipes for the Ages</Navbar.Brand>
                    <Navbar.Toggle className="navbar-toggle" aria-controls="navbarScroll"></Navbar.Toggle>
                    <Navbar.Collapse className="navbar-collapse" id="navbarScroll">
                        <Nav className="me-auto my-2 my-lg-3" style={{maxHeight: '100px'}} navbarScroll>

                        </Nav>
                        <Form onSubmit={getSearch} className="d-flex">
                            <FormControl type="search" placeholder="Search Recipes" className="me-2" value={search}
                                         onChange={updateSearch} aria-label="search"></FormControl>
                            <Button className="search-btn" variant="secondary" type="submit">
                                <h5>Search</h5>
                            </Button>
                        </Form>
                    </Navbar.Collapse>

                </Container>
            </Navbar>
            {recipes.length > 0 ? (
                <section className="hero">
                    <div className="container">
                        <div className="grid">
                            {recipes.map(recipe => (
                                <RecipeBox
                                    key={recipe.recipe.uri}
                                    title={recipe.recipe.label}
                                    image={recipe.recipe.image}
                                    calories={recipe.recipe.calories}
                                    ingredients={recipe.recipe.ingredients}
                                    link={recipe.recipe.url}
                                    ingredients={recipe.recipe.ingredients}
                                    source={recipe.recipe.source}
                                    healthLabels={recipe.recipe.healthLabels}
                                    servings={recipe.recipe.yield}
                                />
                            ))}
                        </div>
                        <div className="d-flex justify-content-between">
                            <Button className="prev-btn" variant="secondary" onClick={prevClick}
                                    type="submit">Previous</Button>
                            <Button className="next-btn" variant="secondary" onClick={nextClick}
                                    type="submit">Next</Button>
                        </div>

                    </div>

                </section>

            ) : (
                <h2>Sorry !! No Recipes Found</h2>
            )}
        </>
    );
};

export default App;
load resultset edamam-api
1个回答
0
投票

在 20 的第一个响应中,JSON 响应应具有:

"_links":{"next":{"href": "[URL]"

此 URL 将返回接下来的 20 个响应(从 21 到 40)

© www.soinside.com 2019 - 2024. All rights reserved.