Вызов функции компонента React обновляет только один экземпляр компонента

У меня есть компонент с именем правая вкладка, подобный этому

const RightTab = ({ data }) => {
  return (
    <div className="RightTab flex__container " onClick={data.onClick}>
      <img src={data.icon} alt="Dashboard Icon" />
      <p className="p__poppins">{data.name}</p>
      {data.dropDown === true ? (
        <div className="dropdown__icon">
          <img src={Assets.Arrow} alt="Arrow" />
        </div>
      ) : (
        <div className="nothing"></div>
      )}
    </div>
  );
};

export default RightTab;

Вкладка имеет активное состояние в своем CSS, как это

.RightTab.active {
  background-color: var(--primaryGreen);
}

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

const dataArray = [
  {
    name: "Dashboard",
    icon: Assets.Dashboard,
    dropDown: false,
    onClick: handleDashBoardClick,
  },
  {
    name: "Inventory",
    icon: Assets.Inventory,
    dropDown: true,
    onClick: handleInventoryClick,
  },
  {
    name: "Reports",
    icon: Assets.Reports,
    dropDown: true,
    onClick: handleReportsClick,
  },
];

Вот как я передаю реквизит.

  <RightTab data={dataArray[0]} />
  <RightTab data={dataArray[1]} />
  <RightTab data={dataArray[2]} />

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

Функция добавляет активный класс состоит в том, чтобы заставить фон менять цвет. Однако каждый раз, когда я нажимаю на компонент это только меняет фон первого появления. И, как вы могли заметить, я вызываю компонент трижды. Независимо от того, какой компонент я нажимаю фон меняется только у первых.

Вот пример функции, которая находится на объекте prop.

const handleDashBoardClick = () => {
  const element = document.querySelector(".RightTab");
  element.classList.toggle("active");
};

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

const element = document.querySelector(".RightTab"); это возвращает первый элемент на странице, соответствующий «.RightTab» — ​​он никогда не вернет второй или третий такой элемент.
James 06.04.2022 14:16
Получение данных из формы с помощью JavaScript - краткое руководство
Получение данных из формы с помощью JavaScript - краткое руководство
Получить данные из формы с помощью JS очень просто: вы запрашиваете элемент формы, передаете его конструктору new FormData() и, наконец, получаете...
Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Сравнение структур данных: Массивы и объекты в Javascript
Сравнение структур данных: Массивы и объекты в Javascript
Итак, вы изучили основы JavaScript и хотите перейти к изучению структур данных. Мотивация для изучения/понимания Структур данных может быть разной,...
Создание собственной системы электронной коммерции на базе Keystone.js - настройка среды и базовые модели
Создание собственной системы электронной коммерции на базе Keystone.js - настройка среды и базовые модели
Прошлая статья была первой из цикла статей о создании системы электронной коммерции с использованием Keystone.js, и она была посвящена главным образом...
Приложение для отслеживания бюджета на React js для начинающих
Приложение для отслеживания бюджета на React js для начинающих
Обучение на практике - это проверенная тема для достижения успеха в любой области. Если вы знаете контекст фразы "Практика делает человека...
0
1
20
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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

Кроме того, способ добавления активного класса не рекомендуется, поскольку вы смешиваете реакцию с чистым js для обработки имен классов CSS.

Я бы порекомендовал иметь обработчик одного клика, который переключает активный класс для всех компонентов nRightTab:

const MainComponent = () => {
  const [classNames, setClassNames] = useState([]);
  
  const handleClick = (name) => 
  {
    const toggledActiveClass = classNames.indexOf('active') === -1
      ? classNames.concat(['active'])
      : classNames.filter((className) => className !== 'active');
      
    setClassNames(toggledActiveClass);
    
    switch (name) {
      case 'Dashboard';
        // do something
        break;
        
        case 'Inventory':
        // ....
        break;
    }
  }
  
  const dataArray = [
    {
      name: "Dashboard",
      icon: Assets.Dashboard,
      dropDown: false,
      onClick: handleClick.bind(null, 'Dashboard'),
    },
    {
      name: "Inventory",
      icon: Assets.Inventory,
      dropDown: true,
      onClick: handleClick.bind(null, 'Inventory'),
    },
    {
      name: "Reports",
      icon: Assets.Reports,
      dropDown: true,
      onClick: handleClick.bind(null, 'Reports'),
    },
  ];

  return (
    <>
      {dataArray.map((data) => 
        <RightTab key={data.name} 
                  data={data} 
                  classNames={classNames} />)}
    </>
  );
};

const RightTab = ({ data, classNames }) => {
  return (
    <div className={classNames.concat(['RightTab flex__container']).join(' ')} 
         onClick={data.onClick}>
      <img src={data.icon} alt="Dashboard Icon" />
      <p className="p__poppins">{data.name}</p>
      {data.dropDown === true ? (
        <div className="dropdown__icon">
          <img src={Assets.Arrow} alt="Arrow" />
        </div>
      ) : (
        <div className="nothing"></div>
      )}
    </div>
  );
};

Ух ты. Это просто сработало. Спасибо, Ман.

AmohPrince 06.04.2022 15:10

Другие вопросы по теме