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

السؤال

نشر

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

أريد القيام بفلترة بواسطة checkbox   حسب نوع منتجات قمت بجلبها بواسطة api.

أولا قمت بتحديد أنواع المنتجات

 // Categories Array
  const categories = products.map(product => product.category)
  .reduce((acc,item) => ((acc.includes(item)) ? acc : [...acc,item]),[])

ثم قمت بتكوين مصفوفة تحتوي نوع المنتج الذي أريد إخياره

const [selected, setSelected] = useState([]);
  const handleCheck = (e) => {
    const { value, checked } = e.target;
    if (checked === true) {
      setSelected((pre) => [...pre, value]);
    } else {
        setSelected((pre) => [...pre.filter((item) => item !== value)]);
    }
  }

الآن تأتي عملية الفلترة

let checked = products.filter(item => selected.indexOf(item.category) !== -1)

المشكلة التي واجهتني هي في كيفية عرض المنتجات الدي إخترتها حيث قمت ب:

if (checked.length === 0) {
    setProducts(products)
  } else {
    setProducts(checked)
  }

لكن هذا الكود لايظهر شيئا.

شكرا على المساعدة.

Recommended Posts

  • 0
نشر

يمكنك استخدام هذا الكود.

{checked.forEach((product) => ( 
  <div key={product.id}>
      <h3>{product.name}</h3>
	  <p>{product.description}</p>
	  </div> 
))}

في هذا المثال، يتم استخدام forEach() لعرض المنتجات المختارة. يتم تحويل كل عنصر في مصفوفة checked إلى عنصر JSX يتم عرضه في الصفحة. يمكنك استخدام أي عنصر JSX تريده لعرض المنتجات المختارة، ولكن يجب تحديد مفتاح فريد لكل عنصر.

أتمنى أن يكون هذا مفيدًا! أخبرني إذا كان لديك أي أسئلة أخرى.

  • 0
نشر

اخي الفاضل يمكنك استخدام دالة تقوم بعملية الفلترة وترجع القائمة

هنا في هذا الكود استخدمت ال text input لتسهيل الشرح ويمكنك استخدام المبدأ على اي شيء بعدها

تم جلب البيانات من الapi في useEffect وتقوم بعمل تحديث للstate المسمى list عن طريق updateList

وعند عمل تغيير في قيمة البحث (او ال checkbox) يتم تحديث قيمة الstate المسمى filter داخل الدالة المسؤولة عن التجاوب مع حدث التغيير handleSearch

وفي دالة searching

يتم النظر في قيمة الfilter اذا كانت لها قيمة (او selected) يتم فلترة القائمة واعادة الlist الجديدة

اما اذا لم يكن هناك فلتر محدد فيتم ارجاع القائمة الاصلية

 

ويتم عمل map على القيمة المرجعة من دالة searching

لاحظ استعمال التعبير cardsList?.map

باستخدام ?

حيث تنبه الكود انه اذا كانت القائمة فارغة فلا يطبق عملية الmap (في حالة لم يتم جلب البيانات او كانت البيانات فارغة اصلا)

import React, { useEffect, useState } from 'react';
import css from './App.module.css';
import axios from 'axios';

const Card = ({id, credit_card_type, credit_card_expiry_date, credit_card_number}) => {
  return (
      <div className={css.card}>
        <h4>{credit_card_type}</h4>
        <p>{credit_card_number}</p>
        <strong>{credit_card_expiry_date}</strong>
      </div>
  );
};

function App() {
  const [filter, setFilter] = useState('');
  const [list, updateList] = useState(null);
  useEffect(() => {
    const getCards =  async () => {
      const response = await axios.get("https://random-data-api.com/api/v2/credit_cards",{
        params:{
          size:10
        }
      })
      updateList(response.data)
    }
    getCards();
  },[]);

  const handleSearch = (e) => {
    setFilter(e.target.value);
  }

  const searching = () => {
    if(filter){
      return list.filter(item => item.credit_card_type.toLowerCase().includes(filter.toLowerCase()));
    } else {
      return list;
    }
  }


  const cardsList = searching();

  const cards = cardsList?.map(item => (
    <Card key={item.id} {...item} />
  ));

  return (
    <>
      <input type="search" placeholder="Search" onChange={handleSearch} value={filter} />
      <div className={css.container}>
        {cards}
      </div>
    </>
  );
}

export default App;

 

  • 0
نشر
بتاريخ 1 ساعة قال Mohammed Fahmy3:

يمكنك استخدام هذا الكود.

{checked.forEach((product) => ( 
  <div key={product.id}>
      <h3>{product.name}</h3>
	  <p>{product.description}</p>
	  </div> 
))}

في هذا المثال، يتم استخدام forEach() لعرض المنتجات المختارة. يتم تحويل كل عنصر في مصفوفة checked إلى عنصر JSX يتم عرضه في الصفحة. يمكنك استخدام أي عنصر JSX تريده لعرض المنتجات المختارة، ولكن يجب تحديد مفتاح فريد لكل عنصر.

أتمنى أن يكون هذا مفيدًا! أخبرني إذا كان لديك أي أسئلة أخرى.

شكرا لكن يبدو أنك لم تفهم ماذا أقصد بالضبط.

المشكلة في كيفية التنسيق بين products و checked يعني في الأول يجب أن تظهر جميع المنتجات و التي قمت بتسميتها products ثم تطبق الفلترة و بالتالي صرت أتحدث عن checked.

أنا وجدت حلا و قد عمل بشكل جيد لكن أعتقد أنه ليس best practice بسبب كثرة المتغيرات

let filtered;
checked.length === 0 ? filtered = products : filtered = checked 

 

بتاريخ 1 ساعة قال Asem Mohamed:

اخي الفاضل يمكنك استخدام دالة تقوم بعملية الفلترة وترجع القائمة

هنا في هذا الكود استخدمت ال text input لتسهيل الشرح ويمكنك استخدام المبدأ على اي شيء بعدها

تم جلب البيانات من الapi في useEffect وتقوم بعمل تحديث للstate المسمى list عن طريق updateList

وعند عمل تغيير في قيمة البحث (او ال checkbox) يتم تحديث قيمة الstate المسمى filter داخل الدالة المسؤولة عن التجاوب مع حدث التغيير handleSearch

وفي دالة searching

يتم النظر في قيمة الfilter اذا كانت لها قيمة (او selected) يتم فلترة القائمة واعادة الlist الجديدة

اما اذا لم يكن هناك فلتر محدد فيتم ارجاع القائمة الاصلية

 

ويتم عمل map على القيمة المرجعة من دالة searching

لاحظ استعمال التعبير cardsList?.map

باستخدام ?

حيث تنبه الكود انه اذا كانت القائمة فارغة فلا يطبق عملية الmap (في حالة لم يتم جلب البيانات او كانت البيانات فارغة اصلا)

import React, { useEffect, useState } from 'react';
import css from './App.module.css';
import axios from 'axios';

const Card = ({id, credit_card_type, credit_card_expiry_date, credit_card_number}) => {
  return (
      <div className={css.card}>
        <h4>{credit_card_type}</h4>
        <p>{credit_card_number}</p>
        <strong>{credit_card_expiry_date}</strong>
      </div>
  );
};

function App() {
  const [filter, setFilter] = useState('');
  const [list, updateList] = useState(null);
  useEffect(() => {
    const getCards =  async () => {
      const response = await axios.get("https://random-data-api.com/api/v2/credit_cards",{
        params:{
          size:10
        }
      })
      updateList(response.data)
    }
    getCards();
  },[]);

  const handleSearch = (e) => {
    setFilter(e.target.value);
  }

  const searching = () => {
    if(filter){
      return list.filter(item => item.credit_card_type.toLowerCase().includes(filter.toLowerCase()));
    } else {
      return list;
    }
  }


  const cardsList = searching();

  const cards = cardsList?.map(item => (
    <Card key={item.id} {...item} />
  ));

  return (
    <>
      <input type="search" placeholder="Search" onChange={handleSearch} value={filter} />
      <div className={css.container}>
        {cards}
      </div>
    </>
  );
}

export default App;

 

لو سمحت هل ممكن أطلع على المشروع لعلني أجد ما يفيدني.

شكرا.

  • 0
نشر
بتاريخ 2 ساعة قال محمود سعداوي:

شكرا لكن يبدو أنك لم تفهم ماذا أقصد بالضبط.

المشكلة في كيفية التنسيق بين products و checked يعني في الأول يجب أن تظهر جميع المنتجات و التي قمت بتسميتها products ثم تطبق الفلترة و بالتالي صرت أتحدث عن checked.

أنا وجدت حلا و قد عمل بشكل جيد لكن أعتقد أنه ليس best practice بسبب كثرة المتغيرات

let filtered;
checked.length === 0 ? filtered = products : filtered = checked 
 

لو سمحت هل ممكن أطلع على المشروع لعلني أجد ما يفيدني.

شكرا.

يمكنك استخدام الكود التالي:

const filtered = (selected.length === 0) ? products : products.filter(item => selected.includes(item.category))

وبهذا الشكل، إذا لم يتم تحديد أي صنف، فستعود المنتجات كما هي، وإذا تم تحديد أي صنف، فسيتم تصفية المنتجات بناءً على الصنف المحدد.

بالنسبة للمتغيرات الإضافية التي كنت قد استخدمتها سابقًا، يمكنك الاستغناء عنها بسهولة من خلال تطبيق العبارة السابقة مباشرة في الدالة الخاصة بالفلترة.

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

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

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

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   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.

  • إعلانات

  • تابعنا على



×
×
  • أضف...