简体   繁体   English

如何在 React 上按成分过滤

[英]How to filter by ingredients on React

Currently I can filter by 1 ingredient, but when i try to select multiple ingredients (checkboxes), My recipes disappear as "ingredient1, ingredient2" is being passed to my searchfield rather than ingredient 1 & ingredient2.目前我可以按 1 种成分过滤,但是当我尝试 select 多种成分(复选框)时,我的食谱消失了,因为“成分 1、成分 2”被传递到我的搜索字段而不是成分 1 和成分 2。

My code for my search/filter is我的搜索/过滤器代码是

import React, { useState } from "react";
import DisplayFoodItems from "./DisplayFoodItems";
import { ingredients } from "../data/Ingredients";

function Search({ details }) {
  const [searchField, setSearchField] = useState("");
  const [checked, setChecked] = useState([]);
  const all = [...checked];
  const filtered = details.filter((entry) => {
    //Search box
    if (entry.name.toLowerCase().includes(searchField.toLowerCase()) ||
      entry.catagory.toLowerCase().includes(searchField.toLocaleLowerCase())) {
      return (
        entry.name.toLowerCase().includes(searchField.toLowerCase()) ||
        entry.catagory.toLowerCase().includes(searchField.toLocaleLowerCase())
      )
    }
    //Filter checkboxes
    for (var i = 0; i < entry.ingredients.length; i++) {
      console.log(searchField)
      if (entry.ingredients[i].toLowerCase().includes(searchField.toLocaleLowerCase())) {
        return (
          entry.ingredients[i].toLowerCase().includes(searchField.toLocaleLowerCase())
        );
      }
    }
  }
  );
  const handleToggle = c => () => {
    // return the first index or -1
    const clickedBox = checked.indexOf(c);
    if (clickedBox === -1) {
      all.push(c);
      console.log(all)
      setSearchField(all.toString())

    } else {
      all.splice(clickedBox, 1);
      setSearchField("")
    }
    console.log(all);
    setChecked(all);
  };
  return (
    <>
      <div>
        <input id="search"
          className="form-control"
          type="text"
          placeholder="Search by recipe name or catagory"
          onChange={(e) => setSearchField(e.target.value)}
        />
      </div>
      <div>
        {ingredients.map((ingredient, index) => (
          <label key={index} className="form-check-label">
            <input
              onChange={handleToggle(ingredient.name)}
              type="checkbox"
              className="mr-2"
            />
            {ingredient.name}</label>
        ))}
        <hr></hr>
      </div>
      <div class="flex">
        <DisplayFoodItems foodList={filtered} />
      </div>
    </>
  );
}
export default Search;

Here is a picture of my screen if it helps at all如果有帮助的话,这是我的屏幕图片我的反应屏幕

All checkboxes work individually but for example, if salt and oil when checked together it should return Bacon wrapped chicken and Smashed potatoes, however it returns blank at present.所有复选框都单独工作,但例如,如果同时选中盐和油,它应该返回培根包裹的鸡肉和土豆泥,但目前返回空白。

过滤器未显示正确的输出

I have tried looping the all array and sending that to setSearchField, but again, I cannot get it to work.我试过循环所有数组并将其发送到 setSearchField,但我还是无法让它工作。

I have tried looping through the array of checked ingredients and sending that to the setSearchField.我尝试遍历已检查成分的数组并将其发送到 setSearchField。 Im expecting recipes to appear if they contain an ingredient that has been checked.如果食谱中含有经过检查的成分,我希望它们会出现。

If I understand correctly you want something like this?如果我理解正确的话,你想要这样的东西吗?

const foodList = [
    { name: "Food 1", ingredients: ["Salt"] },
    { name: "Food 2", ingredients: ["Oil"] },
    { name: "Food 3", ingredients: ["Milk"] },
    { name: "Food 4", ingredients: ["Salt", "Oil"] },
    { name: "Food 5", ingredients: ["Oil", "Milk"] },
    { name: "Food 6", ingredients: ["Oil", "Salt", "Milk"] },
];
const ingredientList = ["Salt", "Oil", "Milk"]

const Example = () => {
    const [ingredients, setIngredients] = useState([]);

    const filtered = foodList.filter(food => {
        return ingredients.length === 0
            || food.ingredients.length > 0 && ingredients.every(selectedIngredient =>
               food.ingredients.some(foodIngredient => foodIngredient.toLowerCase() === selectedIngredient.toLowerCase()));
    });

    return (
        <div>
            <h2>Filter</h2>
            {
                ingredientList.map((ingredient, i) => {
                    const checked = ingredients.some(selectedIngredient => ingredient.toLowerCase() === selectedIngredient.toLowerCase());
                    return (
                        <label key={`ingredient-${i}`}>
                            <input
                                type="checkbox"
                                checked={checked}
                                onChange={() => {
                                    if (checked) {
                                        setIngredients(ingredients.filter(selectedIngredient => ingredient.toLowerCase()!== selectedIngredient.toLowerCase()))
                                    }
                                    else {
                                        setIngredients([...ingredients, ingredient]);
                                    }
                                }} />
                            {ingredient}
                        </label>
                    );
                })
            }
            <br />
            <br />
            <h2>Food list</h2>
            <pre>{JSON.stringify(filtered, null, 4)}</pre>
        </div>
    );
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM