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

السؤال

نشر

أقوم بإنشاء جدول في React يحتوي على عدة صفوف، ولكل صف، سيكون هناك مكون React يسمى AutoShopPricesExpanded يحتوي على مزيد من التفاصيل حول أسعار ذلك الصف، عندما أنقر على صف واحد، أريد أن يتم عرض مكون واحد فقط أسفل ذلك الصف.

حاليًا، يقوم الكود بعرض جميع المكونات لكل صف عندما ينقر المستخدم على زر 'تبديل العرض'.

سؤالي هو: كيف يمكنني عرض مكون واحد فقط للصف ذي الصلة.

الكود أدناه هو ما لدي حاليًا:

import { Box, Text, Table, Tbody, Td, Th, Thead, Tr} from '@chakra-ui/react';
import {AutoShopPriceExpand} from './autoShopPriceExpand';
import { useState } from 'react';

export const AutoShopPricesList = ({filteredAutoShopPricesLists}:{filteredAutoShopPricesLists: any}) => {
    const [isOpen, setIsOpen] = useState(false);
    function toggle() {
        setIsOpen((isOpen) => !isOpen);
    }

    return (
        <Box py={1}>
            <Table variant='striped'>
                <Thead>
                    <Tr>
                        <Th>Vehicle</Th>
                        <Th>Service</Th>
                        <Th isNumeric>Price</Th>
                    </Tr>
                </Thead>
                <Tbody>
                    {filteredAutoShopPricesLists.map((autoshop: any)=>{
                        return(
                            <>
                                <button onClick={toggle}>Toggle show</button>
                                <Tr key = "lol">
                                    <Td>{autoshop.car_year} {autoshop.car_make} {autoshop.car_model} <br/> <Text color='gray' fontSize='sm'> {autoshop.car_trim} </Text></Td>
                                    <Td>{autoshop.service} <br/>  <Text color='gray' fontSize='sm'>{autoshop.date_of_quote} </Text> </Td>
                                    <Td isNumeric> ${autoshop.service_price} <br/>  <Text color='gray' fontSize='sm'>{autoshop.source_of_price} </Text></Td>
                                </Tr>
                                {isOpen && <AutoShopPriceExpand details = {autoshop}/>}
                            </>
                        );
                        
                    })}
                </Tbody> 
            </Table>  
        </Box>
    );
};

 

Recommended Posts

  • 0
نشر

المشكلة هي أن دالة toggle تقوم بتغيير حالة isOpen العامة، وهذا يؤدي إلى فتح أو إغلاق كل الصفوف مرة واحدة عند النقر على أي زر "تبديل العرض".

 يجب تعديل الكود لاستخدام متغير expandedRowIndex الذي يشير إلى صف محدد يتم فتحه. بذلك، يمكنك فقط فتح صف واحد في كل مرة، وذلك باستخدام الحالة المحلية

هنا كيف يمكن عرض مكون AutoShopPriceExpand فقط للصف ذي الصلة:

1. نحتاج إضافة متغير محلي isExpanded يخزن ID الصف المفتوح:

const [expandedRowIndex, setExpandedRowIndex] = useState(null);

2. نضيف ID لكل صف:

{filteredAutoShopPricesLists.map((autoshop, index) => {
  return (
    <Tr key={autoshop.id}>
      ...
    </Tr>
  )
})}

3. للنقرة على الصف يقوم بتحديد ID:

const toggleExpand = (id) => {
  setExpandedRowIndex(expandedRowIndex === id ? null : id);
}

4. ونعرض المكون بناء على ID:

<Tr onClick={() => toggleExpand(autoshop.id)}>
  ...
</Tr>

{expandedRowIndex === autoshop.id && (
  <AutoShopPriceExpand details={autoshop}/> 
)}

بهذا سيتم عرض مكون واحد فقط للصف المنقور عليه.

  • 0
نشر

المشكلة كما ذكر صديقي خالد، تكمن في أن تغيير حالة الضغط isOpen عامة.

لذلك اليك حلا اخر لنفس المشكلة.

الحل يكون عن طريق انشاء حالة جديدة مكونة من object، يحوي على ال key الخاص بكل صف كاسم مميز للعنصر، حيث يتم اضافة المفتاح بشكل ديناميكي لل object عند الضغط، ويتم اعطاؤه القيمة true عند أول ضغطة، وبعدها تبديل القيمة بين ال true وال fasle عند النقر.

هذا الكود سيوضح أكثر:

import { useState } from 'react';

export const AutoShopPricesList = ({ filteredAutoShopPricesLists }: { filteredAutoShopPricesLists: any }) => {
  // القيمة الابتدائية هي اوبجكت فارغ
  const [isOpenMap, setIsOpenMap] = useState<{ [key: string]: boolean }>({});

  // جلب المفتاح الخاص بكل صف واضافته الى الاوبجكت ديناميكيا، وفي حال لم يكن موجودا عند النقر اعط قيمة ترو ليفتح
  // وان كان موجودا قم بتبديل قيمة الفتح عند النقر
    function toggle(rowKey: string) {
    setIsOpenMap((prevMap) => ({
      ...prevMap,
      [rowKey]: typeof prevMap[rowKey] === 'undefined' ? true : !prevMap[rowKey],
    }));
  }

  return (
    // هيكل الجدول كما هو في كودك

    {filteredAutoShopPricesLists.map((autoshop: any) => {
      const rowKey = autoshop.uniqueIdentifier; // رقم مميز لكل عنصر لديك في لائحة الأسعار
      return (
        <>
          {/*  مرر الرقم المميز الذي عرفناه سابقا */}
          <button onClick={() => toggle(rowKey)}>Toggle show</button>
          <Tr key={rowKey}>
            {/* لاشيء يتغير هنا */}
          </Tr>
 		 {/* قم بعرض العنصر الاضافي لكل صف في حال كانت قيمة هذه الصف ترو */}
          {isOpenMap[rowKey] && <AutoShopPriceExpand details={autoshop} />}
        </>
      );
    })}
  );
};

قد تبدو هذه الطريقة معقدة في البداية، ولكنها في الحقيقة جد مستعملة، وخاصة فكرة  انشاء خواص ضمن object باستخدام الأقواس المربعة []، والوصول اليها بواسطة الأقواس المربعة ذاتها (عوضا عن النقطة).

بالتوفيق!

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

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

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

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

  • إعلانات

  • تابعنا على



×
×
  • أضف...