Как прокручивать и расширять аккордеон с помощью нажатия на значок компонента?

У меня есть компонент MainContent со своим дочерним компонентом AddMock. В MainContent есть таблица, в которой показан некоторый список элементов. У него есть определенное действие в каждой строке, такое как просмотр и редактирование, которые отображаются с помощью значков с помощью реакции семантического интерфейса. Нажимая на каждый значок, мне нужно прокрутить вверх и развернуть аккордеон. Аккордеон находится в AddMock.

// AddMock.js
const AddMock = () => {
  return (
    <div className="row">
      <Accordion style={{ paddingLeft: "32px" }}>
        <Card className="collapseStyle">
          <Card.Header>
            <Accordion.Toggle as={Button} variant="link" eventKey="0">
              Add Mock
            </Accordion.Toggle>
          </Card.Header>
          <Accordion.Collapse eventKey="0">
            <Card.Body>
              <Container className="mockbody">
                <Header as="h3">Hierarchy</Header>
                <TabContent />
              </Container>
            </Card.Body>
          </Accordion.Collapse>
        </Card>
      </Accordion>
    </div>
  );
};

Ниже представлен файл MainContent.js.

const MainContent = () => {
  
  return (
    <div>
      <AddMock />
      <div className="container-fluid">
        <div className="row">
          <div className="col-md-12">
            <div className="card">
              <div className="card-header card-header-info">
                <h4 className="card-title ">MOCK</h4>
              </div>
              <div className="card-body">
                <form>
                  {loading ? (
                    <div className="table-responsive">
                      <table className="table">
                        <thead>
                          <tr>
                            <th>AppName</th>
                            <th>Parent_App</th>
                            <th>Created_Date</th>
                            <th>Req_Path</th>
                            <th>Resp_Code</th>
                            <th>Resp_Content_Type</th>
                            <th>Resp_Delay</th>
                            <th>Action</th>
                          </tr>
                        </thead>
                        <tbody>
                          {data.map((routes, index) => {
                            return routes.map(contents, index);
                          })}
                        </tbody>
                      </table>
                    </div>
                  ) : (
                    <Spinner
                      animation="border"
                      style={{ marginLeft: "620px" }}
                    />
                  )}
                </form>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  );
};

Можно ли реализовать это с помощью window.scrollTo() или любого другого лучшего способа реализовать это в реакции?


person Akhil Suseelan    schedule 21.08.2020    source источник
comment
Я думаю, вы можете использовать refs в этой ситуации. Проверьте это: stackoverflow.com/questions/ 43441856/   -  person kubilay salih    schedule 22.08.2020
comment
@kubilaysalih: Можете ли вы привести пример того, как я могу добавить это в моем случае?   -  person Akhil Suseelan    schedule 22.08.2020
comment
вот пример: codesandbox.io/s/ также проверьте эту библиотеку. вы можете использовать реферальную версию с плавной анимацией github.com/ganderzz/react-scroll-to   -  person kubilay salih    schedule 22.08.2020


Ответы (1)


Использование ссылки

Для начала у нас может быть состояние, которое сохраняет eventKey активного Аккордеона.

const [activeKey, setActiveKey] = useState("");

После этого мы используем ref для нашего компонента React-Bootstrap Accordion. Нам нужно использовать Forwarded Refs позже, чтобы, по крайней мере, назначить ссылку на самый верхний DOM. элемент компонента Accordion, чтобы мы могли перейти к нему.

Что касается значка, взгляните на его событие onClick, оно просто устанавливает activeKey в "0", которое сопоставляется с eventKey вашего компонента Accordion.Collapse. Это послужит отправной точкой для его расширения.

// we are going to need a ref to the Accordion element go get its position/use the scrollIntoView function
const accordElem = useRef(null);

const handleClickEdit = () => {
  setActiveKey("0"); // "0" here is as defined in your Accordion.Collapse eventKey
  accordElem.current.scrollIntoView({
    behavior: "smooth",
    block: "end",
    inline: "nearest"
  }); // initiate scroll to the "AddMock" Accordion component
};

return (
  <div>
    <AddMock
      activeKey={activeKey}
      setActiveKey={setActiveKey}
      ref={accordElem}
    />

    ...

    <Icon
      name="pencil"
      size="huge"
      style={{ cursor: "pointer" }}
      onClick={() => handleClickEdit("0")}
    />

Для прокрутки мы можем использовать https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView. Кроме того, конечно, есть и другие альтернативы, такие как scrollTo

Наконец, вот как выглядит наш компонент Accordion с перенаправленной ссылкой и использованием свойства activeKey, взятого из родительского состояния:

const AddMock = React.forwardRef((props, ref) => {
  // optional re-toggling of expanded accordion
  function handleClickToggle(eventKey) {
    if (eventKey === props.activeKey) {
      props.setActiveKey("");
    } else {
      props.setActiveKey(eventKey);
    }
  }

  return (
    <div className="row" ref={ref}>
      <Accordion style={{ paddingLeft: "32px" }} activeKey={props.activeKey}>
        <Card className="collapseStyle">
          <Card.Header>
            <Accordion.Toggle
              as={Button}
              variant="link"
              eventKey="0"
              onClick={() => handleClickToggle("0")}
            >
              Add Mock
            </Accordion.Toggle>
          </Card.Header>
          <Accordion.Collapse eventKey="0">
            <Card.Body>
              ...

CodeSandBox: https://codesandbox.io/s/react-semantic-ui-react-bootstrap-3ndyl?file=/src/App.js:2444-3230

person 95faf8e76605e973    schedule 27.08.2020
comment
Спасибо за вашу помощь, и я ценю ваши усилия :) - person Akhil Suseelan; 27.08.2020