如何在 NextJS 中处理动态创建的选项卡及其状态

问题描述 投票:0回答:1

我有一个要求,我需要在 nextjs 中创建一个包含选项卡组件的 Web 应用程序。

这个想法是,这将处理每个选项卡中的多个实体,例如,我有一个搜索栏来选择不同的产品,当我选择一个产品时,会使用该产品信息以及用户手动填写的表单创建一个新选项卡.

每次我选择新产品时,都会打开一个新选项卡,但我不应该丢失在第一个选项卡中输入的内容。

我需要能够在选项卡之间切换而不丢失状态。

我想知道有什么简单直接的方法吗?一个简单的例子就很好了。

我已经使用 zustand 实现了这一点,并将每个选项卡内容更改存储在一个变量中,然后在打开选项卡时获取它,但它看起来很脏并且不可维护。

javascript reactjs typescript next.js13
1个回答
0
投票

可以使用 React 的状态管理和上下文 API 简化处理动态创建的选项卡及其在 Next.js 中的状态。

首先,创建一个上下文来管理选项卡的状态。

// 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 handleChange = (e) => {
    setFormData(e.target.value);
    setTabs(tabs.map(tab => tab.id === tabId ? { ...tab, content: e.target.value } : tab));
  };

  return (
    <form>
      <textarea value={formData} onChange={handleChange} />
    </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>
  );
}
© www.soinside.com 2019 - 2024. All rights reserved.