react.js,如何从API数据创建搜索过滤器?

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

我正在尝试在React.js中创建我的第一个搜索栏。我正在尝试使用过滤器方法实现搜索功能。我遇到了过滤器方法的问题,该方法给出了类似“未定义过滤器”的错误。我坚持了2天,看了几本教程和无尽的youtube视频。我猜这是最简单的方法。任何帮助将不胜感激。

import React, { useState, useEffect } from "react";
import Recipe from "./Recipe";
import "./styles.css";

export default function RecipeList() {
  const apiURL = "https://www.themealdb.com/api/json/v1/1/search.php?f=c";
  const [myRecipes, setRecipes] = useState("");
  const [search, setSearch] = useState("");

  // fetch recipe from API
  function fetchRecipes() {
    fetch(apiURL)
      .then(response => response.json())
      .then(data => setRecipes(data.meals))
      .catch(console.log("Error"));
  }

  function onDeleteHandler(index) {
    setRecipes(
      myRecipes.filter((element, filterIndex) => index !== filterIndex)
    );
  }
  useEffect(() => {
    fetchRecipes();
  }, []);

 const filterRecipes = myRecipe.meal.filter( element => {
return element.name.toLowerCase().includes(search.toLocaleLowerCase())
 })
{/* filter method above doesn't work */}

  return (
    <div>
       <label>
          <div className="input-group mb-3 cb-search">
            <input
              type="text"
              className="form-control"
              placeholder="Search for recipes..."
              aria-label="Recipient's username"
              aria-describedby="button-addon2"
              onChange = {e => setSearch (e.target.value)}
            />
            <div className="input-group-append">
              <button
                className="btn btn-outline-secondary"
                type="button"
                id="button-addon2"
              >
                Search
              </button>
            </div>
          </div>
        </label>
      <div>
        <button
          className="btn btn-info cb-button fetch-button"
          onClick={fetchRecipes}
        >
          Fetch Recipe
        </button>
        <br />
        {filterRecipes.map((element, index) => (
        <Recipe    
          key={index}
          index = {index}
          onDelete={onDeleteHandler}
          {...element}
          name = {element.strMeal} 
        />
      ))} 
      {/** name of child component */}
      {/** strMeal is the name of Recipe in API object */}
      </div>
    </div>
  );
}

代码codesandbox的链接

reactjs
2个回答
0
投票

我对您的代码updated code进行了一些更改

  1. const [myRecipes, setRecipes] = useState([]);

如果您打算使用map函数,则应将myRecipes声明为数组。

  1. const filterRecipes = myRecipe.meal.filter( element => { return element.name.toLowerCase().includes(search.toLocaleLowerCase()) })

您传递的错误变量应该是myRecipes

filterRecipes.map((element, index) => (
       <Recipe    
         key={index}
          index = {index}
          onDelete={onDeleteHandler}
          {...element}
          name = {element.strMeal} 
        />

3。使用地图功能之前,应检查是否未定义filterRecipes。

  1. 最后,您的提取API返回错误,无法设置setRecipes。

0
投票

我无法完全解决您的任务,因为该任务的信息量很少,但是我认为我的回答对您有用。

所以,我想引起注意的第一件事是useState函数的参数中的初始状态。在此任务中,它应为:

const [myRecipes, setRecipes] = useState({meals: []});

因为,在获取数据之前,React有时间运行代码,并且到第32行时,它会看到myRecipesmyRecipes中的内容,而不是myRecipe。请支付编写代码时要注意)string除外array

并且在第32行中,我建议您添加一些检查项,以解决您对数据的请求,如:

const filterRecipes = myRecipes.meals.length 
 ?  myRecipes.meals.filter(element => {
    return element.name.toLowerCase().includes(search.toLocaleLowerCase());
  });
 : []

并查看您收到的数据,因为我认为没有像name(element.name)这样的propName元素。

我想,我可以为您提供帮助。如有任何疑问,请在评论中提问。会尽快给您答复。祝你好运

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