اذهب إلى المحتوى

السؤال

نشر

السلام عليكم.

قمت بعمل المشروع التالي: https://react-find-meals.netlify.app/

الرجاء توضيح بعض الأخطاء (حسب إعتقادي بسبب useEffect hook)

1. لما أريد البحث عن طريق إسم الوجبة

مثلا في البداية أكتب "pizza" يقع عرض الأكلة صحيح لكن إذا قمت بفسخها و كتابة مثلا "p" فلا شيء يحدث

2. عندما تظهر الوجبات و أريد أن أختار حسب النوع في القائمة الجانبية يظهر فقط نوع الوجبة الذي قمت بتحديده و لا تظهر بقية الأنواع.

الشيفرة البرمجية:

function App() {
  const [searchMeal, setSearchMeal] = useState("")
  const [meals, setMeals] = useState([])
  const [showMeals, setShowMeals] = useState(false)

  // Fetch Meals API
  const getMeals = async () => {
    const response = await fetch('https://www.themealdb.com/api/json/v1/1/search.php?s')
    const data = await response.json()
    const findMeals = data.meals.map(meal => (
      {
        id: meal.idMeal,
        title: meal.strMeal,
        image: meal.strMealThumb,
        rate: (Math.random() * 5).toFixed(2),
        category: meal.strCategory,
        description: meal.strYoutube,
      }
    ))
    setMeals(findMeals)
  }
  useEffect(() => {
    getMeals()
  }, [])

  // Display Searched Meals
  const getSearchedMeals = (e) => {
    e.preventDefault()
    if(searchMeal !== "") {
      const searched = meals.filter(meal => meal.title.toLowerCase().includes(searchMeal.toLowerCase()))
      setMeals(searched)
    }
    setSearchMeal("")
    setShowMeals(true)
  }

  // filter by category
  const [selected, setSelected] = useState([])
  const categories = meals.map(meal => meal.category)
                          .reduce((acc,item) => 
                            (acc.includes(item) ? acc : [...acc,item])
                            ,[])
  const handleCheck = (e) => {
    const {value, checked} = e.target;
    if (checked === true) {
      setSelected(pre=>[...pre,value])
    }else {
      setSelected(pre=> [...pre.filter(item => item !== value)])
    }
  }
  
  useEffect(() => {
    const filtered = meals.filter(item => selected.includes(item.category))
    setMeals(filtered);
  }, [selected]);

  // Filter By Rate
  
  return (
    <div className="container">
      <Search
        searchMeal = {searchMeal}
        setSearchMeal = {setSearchMeal}
        getSearchedMeals = {getSearchedMeals}
      />
      <div className="main">
        {
          showMeals && <FilterMeal 
            categories = {categories}
            handleCheck = {handleCheck}
          />
        }
        {
          showMeals && <Meals 
            meals = {meals}
            searchMeal = {searchMeal}
          />
        }
      </div>
      
    </div>
  );
}

export default App;

شكرا لكم.

Recommended Posts

  • 0
نشر

مشكلة البحث:

الخطأ في عرض البحث بحيث يعمل البحث فقط إذا تم إدخال الكلمة بالكامل. على سبيل المثال، عند الكتابة "p"، لا يعرض أي شيء.

هذا الخطأ يحدث لأن استخدام الدالة setMeals() في الدالة getSearchedMeals() يعيد قائمة الوجبات إلى حالتها الأصلية، مما يعني أن العرض الحالي للوجبات سيتم إزالته. يجب استخدام حالة جديدة تتضمن النتائج المصفاة دون تغيير الحالة الأصلية لقائمة الوجبات.

لإصلاح هذا الخطأ، يمكن تعديل الدالة getSearchedMeals() على النحو التالي:

const getSearchedMeals = (e) => {
  e.preventDefault();
  if (searchMeal !== "") {
    const searched = meals.filter(meal =>
      meal.title.toLowerCase().includes(searchMeal.toLowerCase())
    );
    setShowMeals(true);
    setMeals(searched);
  } else {
    setShowMeals(false);
  }
  setSearchMeal("");
};

مشكلة تصفية النوع:

تحدث هذه المشكلة لأنه في كل مرة تقوم فيها بتحديد الفئة، تقوم الدالة setMeals() بتعيين القائمة المفلترة إلى قائمة من الوجبات التي تحتوي فقط على النوع الذي تم تحديده. لحل هذه المشكلة، يمكنك استخدام مصفوفة أخرى لتخزين القائمة الأصلية من الوجبات وتقوم بتصفيتها بناءً على النوع وتعيين القائمة المعروضة إلى النتيجة.

يمكنك تعديل الكود كالتالي:

function App() {
    const [searchMeal, setSearchMeal] = useState("");
    const [meals, setMeals] = useState([]);
    const [showMeals, setShowMeals] = useState(false);
    const [originalMeals, setOriginalMeals] = useState([]); // إضافة قائمة الوجبات الأصلية

    // Fetch Meals API
    const getMeals = async () => {
        const response = await fetch(
            "https://www.themealdb.com/api/json/v1/1/search.php?s"
        );
        const data = await response.json();
        const findMeals = data.meals.map((meal) => ({
            id: meal.idMeal,
            title: meal.strMeal,
            image: meal.strMealThumb,
            rate: (Math.random() * 5).toFixed(2),
            category: meal.strCategory,
            description: meal.strYoutube,
        }));
        setMeals(findMeals);
    };
    useEffect(() => {
        getMeals();
    }, []);

    // Display Searched Meals
   const getSearchedMeals = (e) => {
  e.preventDefault();
  if (searchMeal !== "") {
    const searched = meals.filter(meal =>
      meal.title.toLowerCase().includes(searchMeal.toLowerCase())
    );
    setShowMeals(true);
    setMeals(searched);
  } else {
    setShowMeals(false);
  }
  setSearchMeal("");
};

    // filter by category
    const [selected, setSelected] = useState([]);
    const categories = meals
        .map((meal) => meal.category)
        .reduce((acc, item) => (acc.includes(item) ? acc : [...acc, item]), []);
    const handleCheck = (e) => {
        const { value, checked } = e.target;
        if (checked === true) {
            setSelected((pre) => [...pre, value]);
        } else {
            setSelected((pre) => [...pre.filter((item) => item !== value)]);
        }
    };

    useEffect(() => {
        const filtered = meals.filter((item) =>
            selected.includes(item.category)
        );
        setMeals(filtered);
    }, [selected]);

    // Filter By Rate

    return (
        <div className="container">
            <Search
                searchMeal={searchMeal}
                setSearchMeal={setSearchMeal}
                getSearchedMeals={getSearchedMeals}
            />
            <div className="main">
                {showMeals && (
                    <FilterMeal
                        categories={categories}
                        handleCheck={handleCheck}
                    />
                )}
                {showMeals && <Meals meals={meals} searchMeal={searchMeal} />}
            </div>
        </div>
    );
}
export default App;

انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أجب على هذا السؤال...

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.

  • إعلانات

  • تابعنا على



×
×
  • أضف...