как получить доступ к элементу массива refs - PullRequest
0 голосов
/ 04 августа 2020

Мой класс - контейнер вкладок. элемент li, отображающий каждую вкладку. Я использую массив refs для идентификации элементов списка, а также для установки и отключения активной вкладки путем добавления и удаления класса tab-list-active. Я использую версию реакции 16.13.1

Tab

import React, { createRef } from "react";
import {
  MapTo,
  withComponentMappingContext,
  ResponsiveGrid,
} from "@adobe/cq-react-editable-components";

import Tab from "./Tab";
require("./Tabs.css");

const TabsContainerEditConfig = {
  emptyLabel: "Tabs",

  isEmpty: function (props) {
    return !props;
  },
};

export default class TabsContainer extends ResponsiveGrid {
  activeTabRef = this.props.columns.map((x) => createRef(null));

  get containerProps() {
    let containerProps = super.containerProps;
    containerProps.className =
      (containerProps.className || "") + " aem-Grid " + this.props.gridClassNames;
    return containerProps;
  }

  render() {
    if (this.props.columns.length == 0 || !this.props.columns[0].title) {
      return (
        <div {...this.containerProps}>
          {super.childComponents}
          {super.placeholderComponent}
        </div>
      );
    } else {
      let activeTab = "";
      if (this.props.columns[0].title) activeTab = this.props.columns[0].title;

      return (
        <div className="tabs">
          <div {...this.containerProps}>
            <ol className="tab-list">
              {this.props.columns.map((child, id) => {
                let className = "tab-list-item";
                if (activeTab === child.id) {
                  className += " tab-list-active";
                }
                return (
                  <li
                    ref={(el) => (this.activeTabRef[child.id] = el)}
                    key={id}
                    onClick={() => {
                      let prevActiveTab = activeTab;
                      activeTab = child.id;
                      this.activeTabRef[prevActiveTab].current.classList.remove(
                        "tab-list-active",
                      );
                      this.activeTabRef[activeTab].current.classList.add("tab-list-active");
                    }}
                    className={className}
                  >
                    {child.title}
                  </li>
                );
              })}
            </ol>
            <div className="tab-content">
              {this.props.columns.map((child, id) => {
                if (child.id !== activeTab) return undefined;
                return (
                  <div id={child.id} key={id}>
                    {this.childComponents}
                    {this.placeholderComponent}
                  </div>
                );
              })}
            </div>
          </div>
        </div>
      );
    }
  }
}

MapTo("tabscontainer")(withComponentMappingContext(TabsContainer), TabsContainerEditConfig);

Когда я нажимаю на вкладку списка, я получаю сообщение об ошибке. Я не понимал, как добавлять и удалять класс с помощью массива refs для определенного индекса.

Uncaught TypeError: Cannot read property 'classList' of undefined at onClick

1 Ответ

0 голосов
/ 04 августа 2020

Как говорится в моем комментарии: не используйте refs, просто сделайте активную вкладку частью состояния компонента Tabs:

export default class TabsContainer extends ResponsiveGrid {
  constructor(props) {
    super(props);
    const activeTab =
      props.columns && props.columns[0] && props.columns[0].title
        ? props.columns[0].title
        : "";
    this.state = { activeTab };
  }

  get containerProps() {
    let containerProps = super.containerProps;
    containerProps.className =
      (containerProps.className || "") + " aem-Grid " + this.props.gridClassNames;
    return containerProps;
  }

  renderTabBar(columns, activeTab) {
    return (
      <ol className="tab-list">
        {columns.map((child, id) => {
          let className = "tab-list-item";
          if (activeTab === child.id) {
            className += " tab-list-active";
          }
          return (
            <li
              key={id}
              onClick={() => this.setState({ activeTab: child.id })}
              className={className}
            >
              {child.title}
            </li>
          );
        })}
      </ol>
    );
  }

  renderContent(columns, activeTab) {
    return (
      <div className="tab-content">
        {columns.map((child, id) => {
          if (child.id !== activeTab) return undefined;
          return (
            <div id={child.id} key={id}>
              {this.childComponents}
              {this.placeholderComponent}
            </div>
          );
        })}
      </div>
    );
  }

  render() {
    const { columns } = this.props;
    const { activeTab } = this.state;
    if (columns.length === 0 || !columns[0].title) {
      return (
        <div {...this.containerProps}>
          {this.childComponents}
          {this.placeholderComponent}
        </div>
      );
    }
    return (
      <div className="tabs">
        <div {...this.containerProps}>
          {this.renderTabBar(columns, activeTab)}
          {this.renderContent(columns, activeTab)}
        </div>
      </div>
    );
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...