Как показать/скрыть элемент/компонент вложенного массива после отображения внешнего массива с помощью useState в React?

Первоначальная цель:

  • У меня есть 4 компонента, при нажатии на один из компонентов остальные три компонента исчезают, чтобы показать только тот, на который нажали. Повторный щелчок по компоненту переключает все компоненты для повторного отображения.
  • Моя цель — добавить объект информации/описания к каждому из компонентов в массиве, чтобы при переключении компонента другие компоненты по-прежнему исчезали, но теперь отображалось описание в соответствии с переключенным компонентом.
  • Мой мыслительный процесс заключается в том, чтобы установить флаг видимости для элемента описания, установить для него значение false, а переключение определенного компонента изменит флаг на значение true и отобразит описание. Вот мой текущий взгляд на это:
const array = [
    { id: 1, component: <Comp1/>, isVisible: true, 
      info: [{ id: 5, component: <div>info1</div>, isVisibleInfo: false }] },

    { id: 2, component: <Comp2/>, isVisible: true, 
      info: [{ id: 6, component: <div>info2</div>, isVisibleInfo: false }] },

    { id: 3, component: <Comp3/>, isVisible: true, 
      info: [{ id: 7, component: <div>info3</div>, isVisibleInfo: false }] },

    { id: 4, component: <Comp4/>, isVisible: true, 
      info: [{ id: 8, component: <div>info4</div>, isVisibleInfo: false }] }
  ];

  
  export const Test = () => {

    const [items, setItems] = useState(array);
  
    const handleClick = (number) => {
      const triggeredItems = items.map((item) => {
        if (item.id !== number) {
          item.isVisible = !item.isVisible;
        }
  
        return item;
      });
  
      setItems(triggeredItems);
    };

    const handleClickInner = (number) => {
      const triggeredItemsInner = items.info.map((item) => {
        if (item.id !== number) {
          item.isVisibleInfo = !item.isVisibleInfo;
        }
  
        return item;
      });
  
      setItems(triggeredItemsInner);
    };

  
    return (
      <div className = "mt-1 pt-1 pb-3 px-3">
        <div className = "row text-center d-flex my-1">
        {items.map(({ id, component, isVisible, info }) => (
          <div
            key = {id}
            className = "col-lg-3 col-md-6 mb-4 justify-content-center"
            onClick = {() => handleClick(id)}
            hidden = {!isVisible}
          >
            { component }

            {info.map(({ id, component, isVisibleInfo }) => (
            <div
              key = {id}
              className = "col-lg-9 col-md-6 mb-4 justify-content-center"
              onClick = {() => { handleClickInner(id)}}
              hidden = {isVisibleInfo}
            >
              { component }
              
            </div>
          ))}
          </div>
        ))}
        </div>
      </div>
    );
  };
  export default Test;

На данный момент я получаю этот вывод TypeError: Не удается прочитать карту свойства undefined в функции «handleClickInner», потому что я считаю, что карта не может отображать вложенный массив, но в целом я не уверен, что создание этой второй функции является правильным подходом даже.

Все еще многому учусь о React и его методах!

Любые мысли или помощь будут оценены!

items — это не объект, items — это массив объектов. Итак, items.info не определено. Вам нужно будет получить доступ к определенному объекту, чтобы изменить его информационный массив, например. items[0].info.map
Jayce444 11.12.2020 00:14

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

Patrik Kozak 11.12.2020 00:24

Я бы сделал именно то, о чем ты думаешь... звучит как реакция на меня.

Mint 11.12.2020 02:06
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
3
808
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Моя цель - добавить объект информации/описания к каждому из компонентов. в массиве, чтобы при переключении компонента другие компоненты по-прежнему исчезают, но теперь появляется описание в соответствии с переключаемый компонент.

Ты действительно имеешь в виду исчезнуть, не так ли? больше похоже на то, что вы хотите условно визуализировать компонент.

ОБНОВЛЕНО

Я неправильно понял ваши намерения! Теперь они исчезают.

// hooks
const {useState} = React;

function Comp1(){
  return <div><p>Component 1</p></div>
}
function Comp2(){
  return <div><p>Component 2</p></div>
}
function Comp3(){
  return <div><p>Component 3</p></div>
}
function Comp4(){
  return <div><p>Component 4</p></div>
}

const array = [
    { id: 1, component: <Comp1/>, isVisible: true, 
      info: { id: 5, component: <div>info1</div>, isVisibleInfo: false } },

    { id: 2, component: <Comp2/>, isVisible: true, 
      info: { id: 6, component: <div>info2</div>, isVisibleInfo: false } },

    { id: 3, component: <Comp3/>, isVisible: true, 
      info: { id: 7, component: <div>info3</div>, isVisibleInfo: false } },

    { id: 4, component: <Comp4/>, isVisible: true, 
      info: { id: 8, component: <div>info4</div>, isVisibleInfo: false } }
  ];

const Test = () => {

    const [items, setItems] = useState(array);
  
    const handleClick = (number) => {
      
      const triggeredItems = items.map((item) => {
        if (item.id !== number) {
          item.isVisible = !item.isVisible;
        }
        item.info.isVisibleInfo =! item.info.isVisibleInfo
  
        return item;
      });
  
      setItems(triggeredItems);
    };

  
    return (
      <div className = "mt-1 pt-1 pb-3 px-3">
        <div className = "row text-center d-flex my-1">
        {items.map(({ id, component, isVisible, info }) => (
          isVisible ? 
          <div
            key = {id}
            className = "col-lg-3 col-md-6 mb-4 justify-content-center"
            onClick = {() => handleClick(id)}
            hidden = {!isVisible}
          >
            { component }
          {info.isVisibleInfo ? 
          <div
              key = {info.id}
              className = "col-lg-9 col-md-6 mb-4 justify-content-center"
            >
              { info.component }
              
            </div>
            : null}
          </div>
          : null
        ))}
        </div>
      </div>
    );
  };


function App(){
  return (
    <div>
      <Test />
    </div>
  );
};

// Render
ReactDOM.render(
  <App />,
  document.getElementById("react")
);
<div id = "react"></div>

<script src = "https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
    <script src = "https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>

Да, я считаю, что условно рендерить — это правильная терминология. Я проверил ваш код, и на выходе я получаю 3 тега div Info, которые не соответствуют компоненту, на который нажимают, ха-ха. Например, если я нажму <comp1/>, вывод будет "info2, info3, info4". Вместо просто «info1». Это проблема с моей функцией handleClick?

Patrik Kozak 11.12.2020 03:07

Нет, я думал, это и есть твоя цель ^_^. Я обновлю код.

Mint 11.12.2020 12:45

Как раз то, что мне было нужно! Просто из любопытства, возможно ли, чтобы информационный объект находился в собственном теге div за пределами тега div Comp1, например?

Patrik Kozak 11.12.2020 17:34

Компонент может отображать только один div <div><p>hi</p><p>there</p></div> это хорошо, но не <div>1</div><div>2</div>

Mint 12.12.2020 23:45

В этом есть смысл. Я просто подумал, что если бы я обернул <div>1</div><div>2<div/> внешним div, чтобы он выглядел так: <div> <div>1</div><div>2<div/> </div>. Тогда я предполагаю, что <div>1</div> и <div>2</div> будут действовать как отдельные элементы внутри внешнего тега. Однако, когда я проверяю это, кажется, что <div>2</div> все еще действует как дочерний элемент для <div>1</div>. Это просто так? Просто смущен этим.

Patrik Kozak 14.12.2020 05:35

Вы можете сделать это. Подумайте об этом так; компонент должен иметь контейнер div. Так что можно <div className='container'><div>inner 1</div><div>inner2</div></div>

Mint 14.12.2020 13:38

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