Модальный рендеринг реакции в списке

#javascript #reactjs

#javascript #reactjs

Вопрос:

У меня есть список элементов, и для каждого элемента в списке есть кнопка редактирования, чтобы отобразить модальный вариант с деталями этого элемента. Первоначально у меня был один модальный компонент в родительском, и когда я нажимаю кнопку редактирования, он передает видимые значения в родительское состояние, чтобы отобразить модальное.

Проблема в том, что когда я это сделал, весь список был бы повторно отображен, чего я не хочу, потому что в списке могут быть сотни элементов. Итак, прямо сейчас решение, которое у меня есть, заключается в том, что в каждом элементе списка у меня есть модальный, связанный с ним. Это работает, но кажется неправильным, потому что я дублирую код без необходимости.

Код слишком велик, чтобы помещать его здесь, но это соответствующие части:

 import Modal from '../Modal';

const CustomCard = ({
  ...omitted
}) => {
  const [editCustomerModal, setEditCustomerModal] = useState(false);



  const onEditModal = () => {
    setEditCustomerModal(true);
  };

  return (
    <>
      <CustomerModal
        onSuccess={handleUpdateCustomer}
        onCancel={handleCancelModal}
        visible={editCustomerModal}
        title="Edit Customer"
        details={{
          .. ommitted
        }}
      />
      <Card />
         ....data
      </Card>
    </>
  );
};

export default CustomCard;
 
 import CustomCard from '../CustomerCard/index';



const CustomList = ({ dataSource }) => {
  
  return (
    <div>
      {dataSource?.map(i => (
        <CustomCard
          ...props ommitted
        />
      ))}
    </div>
  );
};

export default CustomerList;
 
  •     import CustomerList from './components/CustomerList/index';
    
       // import Modal from './components/AddCustomerModal';
    
    
       const CustomersPage = () => {
         const [editCustomerModal, setEditCustomerModal] = useState(false);
    
         const [editCustomer, setEditCustomer] = useState(null);
    
    
     return (
       <>
    
         // This is where I would want it ideally
         <Modal
           onSuccess={handleSaveCustomerEdit}
           onCancel={handleCancelCustomerEdit}
           visible={editCustomerModal}
           details={editCustomer}
         />
           <CustomerList
             dataSource={data}
    
           />
         </div>
         {/* </ModalContext.Provider> */}
       </>
     );
     

    };

    экспорт страницы пользователя по умолчанию;

Ответ №1:

Вы можете определить один выбранный атрибут useState, который хранит только тот регистр, который вы хотите передать своему модальному.

Например:

 import CustomerList from './components/CustomerList/index';

import Modal from './components/AddCustomerModal';

const CustomersPage = () => {
    const [editCustomerModal, setEditCustomerModal] = useState(false);
    const [editCustomer, setEditCustomer] = useState(null);
    const [selected, setSelected] = useState(null);

    return (
        <>
            <Modal
                onSuccess={handleSaveCustomerEdit}
                onCancel={handleCancelCustomerEdit}
                visible={editCustomerModal}
                details={editCustomer}
                selectedCard={selected}
            />
            
            {dataSource?.map(i => (
                <CustomCard ...props ommitted setSelected={setSelected}/>
                //somewere in CustomCard, trigger the event to set selected props that you want to pass for Modal
                //remember to be careful with nullable object. use selectedCard?.something
            ))}
        </>
    );
};

export default CustomersPage;
 

Комментарии:

1. Но весь список будет повторно отображаться снова, верно? Я пытаюсь избежать рендеринга каждого элемента списка

2. Если вы хотите отобразить элементы, вам нужно было отобразить хотя бы один раз каждый элемент списка. Но в примере я рендерю модальный только один раз.

3. Каждый раз, когда изменяется модальное состояние, список повторно отображается, чего я и пытаюсь избежать. Я хочу модальный как единый компонент, как есть, но я не хочу повторно отображать список каждый раз, когда отображается модальный