reactjs - React'te modallarla bir öğe listesinde modal açmak


Bir öğeler listem var ve listenin her bir öğesinin bir modal açan butonu var.

Benim problemim, bir şeyleri yanlış yapmış olabileceğimi düşünüyorum çünkü 'bir modal aç' tuşuna tıkladığımda çalışmıyor. Çalıştırmayı başardım ama tüm modallar aynı anda açılıyordu ve bunu nasıl düzelteceğimi bulamadım.

İşte tüm kodların bulunduğu benim sandboxım: https://codesandbox.io/s/modal-on-list-sjw7u?file=/src/components/TopBar.tsx

Öğe listem, sandbox'taki MetricsDetailsPage sınıfında ve bu sınıfta modal'i çağırdığım kısım şöyle yapılmıştır:

<FiltersAddition
    dimension={dimension}
    isModalOpen={isShowing}
    toggle={toggle}
/>
<Button onClick={toggle}> Instantiate </Button>

Benim sorunum, eğer benim code sandbox'ımda "https://sjw7u.csb.app/metric/test" adresini açar ve "Instantiate" butonuna tıklarsanız, modalların listedeki her öğe için kopyalandığını göreceksiniz ve ben sadece tıklanan öğenin modalını göstermek istiyorum (yani bir seferde bir tane).

Cevap #1

Gelecekte, soruya ilgili, sorunlu kodu eklemeyi tercih edin.

Sorun, modalı her tekrarda dahil etmeniz ve hangi modalın bir seferde gösterildiğini kontrol eden bir üst durumun olmamasıdır.

Hook'u değiştirmenizi ve onu paylaşılan bir üst durumdan kullanmanızı öneririm:

import { useState } from 'react';
import { IDimension } from '../model/metric';

const useModal = () => {
  // store which has been selected
  const [selected, setSelected] = useState<IDimension>();
  const [isShowing, setIsShowing] = useState<boolean>(false);

  const open = (dimension: IDimension) => {
    setSelected(dimension);
    setIsShowing(true);
  };

  const close = () => {
    setSelected(null);
    setIsShowing(false);
  };

  return {
    isShowing,
    open,
    close,
    selected
  };
};

export default useModal;

Sonra modalinizi döngünün dışına taşıyın:

          <TableBody>
            {metric?.dimensions.map((dimension) => (
              <TableRow key={dimension.name}>
                <TableCell>{dimension.name}</TableCell>
                <TableCell>{dimension.value_type}</TableCell>
                <TableCell>{dimension.doc ? dimension.doc : 'No description available'}</TableCell>
                <TableCell>
                  <Button onClick={() => open(dimension)}> Instantiate </Button>
                </TableCell>
              </TableRow>
            ))}
          </TableBody>
        </Table>
       {/* outside the loop */}
        <FiltersAddition dimension={selected} isModalOpen={isShowing} close={close} />

Değiştirilmiş Codesandbox Demo

İlgili makaleler