Как обрабатывать динамически создаваемые вкладки и их состояние в NextJS

У меня есть требование: мне нужно создать веб-приложение в nextjs, в котором есть компоненты вкладок.

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

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

Мне нужно иметь возможность переключаться между вкладками без потери состояния.

Я хочу знать, есть ли какой-нибудь простой и прямой путь? простой пример будет отличным.

Я добился этого с помощью zustand и сохраняю изменения содержимого каждой вкладки в переменной, а затем извлекаю ее при каждом открытии вкладки, но она выглядит грязной и непригодной для обслуживания.

Поведение ключевого слова "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
0
86
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Обработку динамически создаваемых вкладок и их состояния в Next.js можно упростить с помощью API управления состоянием и контекста React.

Сначала создайте контекст для управления состоянием вкладок.

// contexts/TabsContext.js
import { createContext, useContext, useState } from 'react';

const TabsContext = createContext();

export const useTabs = () => useContext(TabsContext);

export const TabsProvider = ({ children }) => {
  const [tabs, setTabs] = useState([]);
  const [activeTab, setActiveTab] = useState(null);

  const addTab = (tab) => {
    setTabs([...tabs, tab]);
    setActiveTab(tab.id);
  };

  const removeTab = (id) => {
    setTabs(tabs.filter(tab => tab.id !== id));
    if (activeTab === id) {
      setActiveTab(tabs.length > 0 ? tabs[0].id : null);
    }
  };

  const switchTab = (id) => {
    setActiveTab(id);
  };

  return (
    <TabsContext.Provider value = {{ tabs, activeTab, addTab, removeTab, switchTab }}>
      {children}
    </TabsContext.Provider>
  );
};

Этот компонент будет обрабатывать отрисовку вкладок и форм внутри каждой вкладки.

// components/Tabs.js
import { useTabs } from '../contexts/TabsContext';

const Tabs = () => {
  const { tabs, activeTab, addTab, removeTab, switchTab } = useTabs();

  return (
    <div>
      <div className = "tab-list">
        {tabs.map(tab => (
          <button key = {tab.id} onClick = {() => switchTab(tab.id)}>
            {tab.title}
            <span onClick = {() => removeTab(tab.id)}>x</span>
          </button>
        ))}
        <button onClick = {() => addTab({ id: Date.now(), title: 'New Tab', content: '' })}>
          + New Tab
        </button>
      </div>
      <div className = "tab-content">
        {tabs.map(tab => (
          tab.id === activeTab ? <div key = {tab.id}>{tab.content}</div> : null
        ))}
      </div>
    </div>
  );
};

export default Tabs;

Каждая вкладка будет содержать форму, данные которой необходимо сохранить.

// components/TabForm.js
import { useState } from 'react';
import { useTabs } from '../contexts/TabsContext';

const TabForm = ({ tabId }) => {
  const { tabs, setTabs } = useTabs();
  const tab = tabs.find(tab => tab.id === tabId);
  const [formData, setFormData] = useState(tab ? tab.content : '');

  const handleChangeEvent = (e) => {
    setFormData(e.target.value);
    setTabs(tabs.map(tab => tab.id === tabId ? { ...tab, content: e.target.value } : tab));
  };

  return (
    <form>
      <textarea value = {formData} onChange = {handleChangeEvent} />
    </form>
  );
};

export default TabForm;

Оберните основной компонент приложения с помощью TabsProvider, чтобы предоставить контекст всем компонентам.

// pages/_app.js
import { TabsProvider } from '../contexts/TabsContext';

function MyApp({ Component, pageProps }) {
  return (
    <TabsProvider>
      <Component {...pageProps} />
    </TabsProvider>
  );
}

export default MyApp;

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

// pages/index.js
import Tabs from '../components/Tabs';

export default function Home() {
  return (
    <div>
      <h1>Dynamic Tabs Example</h1>
      <Tabs />
    </div>
  );
}

Большое спасибо за ваше время и ответ, так что по сути здесь вы использовали контекст реагирования вместо внешней библиотеки управления состоянием. Но у меня есть еще один вопрос: можно ли как-то не использовать библиотеку управления состоянием и предотвратить повторную отрисовку существующих вкладок при переключении между вкладками? в этом случае мы сохраняем контент и не проводим повторную визуализацию, если вкладка переключается или добавляется, возможно? я все еще новичок, извините, если мой вопрос покажется глупым

ahmed ghanem krid 23.05.2024 10:41

@ahmedghanemkrid Используйте useRef для хранения содержимого каждой вкладки, предотвращая повторную визуализацию при переключении между вкладками.

Saravanan Nandhan 23.05.2024 13:20

как это именно работает?

ahmed ghanem krid 23.05.2024 16:34

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