Переключатель при использовании react-strap открывает все переключатели одновременно

Мой переключатель открывает все обертки одновременно, когда я нажимаю на одну конкретную, что не так?

const SomeData = ({ data, dayNumber }, props) => {
  const Exams = () => {
    const listExams = data.map((item) => (
      <Fragment>
        <Wrap key={item.id}>
          <WrapCard userID={item.userID}>
            <Button color="light" size="lg" block onClick={toggle} style={{ marginBottom: "1rem" }</Button>
            <Collapse isOpen={isOpen}>
              <Card></Card>
            </Collapse>
          </WrapCard>
        </Wrap>
      </Fragment>
    ));
    return listExams;
  };
  const [isOpen, setIsOpen] = useState(false);
  const toggle = () => setIsOpen(!isOpen);
};


person Ana Rodrigues    schedule 16.06.2020    source источник
comment
Ваш isOpen является глобальным для всех элементов на карте. Вот почему. Если вы хотите сделать его индивидуальным, вам нужно будет указать состояние для каждого элемента на карте или создать состояние со всеми идентификаторами ваших элементов и использовать переключение по идентификатору в глобальном состоянии.   -  person CevaComic    schedule 16.06.2020


Ответы (2)


Проверьте отрендеренный HTML. Вы увидите этот блок кода для каждого элемента данных:

     <Fragment>
        <Wrap key="someID">
          <WrapCard userID="someotherID">
            <Button color="light" size="lg" block onClick={toggle} style={{ marginBottom: "1rem" }</Button>
            <Collapse isOpen=!!---SAME VALUE HERE---!!
              <Card></Card>
            </Collapse>
          </WrapCard>
        </Wrap>
      </Fragment>

(Часть текста выше в вашем HTML будет выглядеть иначе, чем то, что я набрал, я разрешил только некоторые из них)

Проблема в том, что я вставил туда ---SAME VALUE HERE---. Все они ссылаются на один и тот же isOpen. Поэтому вам нужно иметь много значений в вашем состоянии, по одному для каждого элемента в данных. Я предполагаю, что у них есть уникальный идентификатор. поэтому вы можете использовать состояние, которое является пустым объектом, и когда вы включаете его: setIsOpen({...isOpen, item.id: true}) и когда вы включаете его, оно закрывается setIsOpen({...isOpen, item.id: false}). Затем проверьте каждый элемент данных, если он должен быть открыт. Это может выглядеть как <Collapse isOpen={isOpen[item.id]}>, который работает только в том случае, если вы хотите, чтобы он был закрыт как состояние по умолчанию (если элемент undefined), поскольку и undefined, и false равны falsy.

Это не сработает, если вы хотите, чтобы состояние по умолчанию было открытым. Тогда вам придется <Collapse isOpen={typeof isOpen[item.id] === 'undefined' || isOpen[item.id] === true}>. Также были бы более элегантные необязательные ответы на цепочки.

person Diesel    schedule 16.06.2020

Я предлагаю вам использовать Складной Использовать Складной

npm install react-collapsible --save
yarn add react-collapsible

После установки этого измените свой код, например:

import Collapsible from 'react-collapsible';

const SomeData = ({ data, dayNumber }, props) => {
  const Exams = () => {
    const listExams = data.map((item) => (
      <Fragment>
        <Wrap key={item.id}>
          <WrapCard userID={item.userID}>
            <Collapsible trigger = {<span><Button color="light" size="lg" block onClick={toggle} style={{ marginBottom: "1rem" }</Button></span>}>
              <Card></Card>
            </Collapsible>
          </WrapCard>
        </Wrap>
      </Fragment>
    ));
    return listExams;
  };
};

person aayush tyagi    schedule 06.11.2020