ReactJS中的简单选项卡组件



我是React.js的新手,我知道状态、组件等基本知识,但我需要:创建一个像这样使用的MyTabsComponent

<MyTabsComponent>
<div title={"Section title 1"}>Content of section 1</div>
<div title={"Section title 2"}>Content of section 2</div>
<div title={"Section title 3"}>Content of section 2</div>
<div title={"Section title 4"}>Content of section 2</div>
<div title={"Section title 5"}>Content of section 2</div>

.
.
.
.
.and so on..............
.
.
.
.
.

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

参见视觉

上面的代码应该呈现如下:

<div class="tabs">
<button class="btn-active">Section title 1</button>
<button class="btn">Section title 2</button>
<button class="btn">Section title 3</button>
<button class="btn">Section title 4</button>
<!--

.
.
.
.
.
.
and so on..........
-->

<div class="view">
Content of section 1
</div>
</div>

我尝试过的:

import React,{useState} from "react";
const MyTabsComponent = () => {
const [title,setTitle] = useState(['Section 1','Section 2','Section 3']);
const [ct,setCt] = useState(null);
return (
<div className="tabs">
<TabButtons tabName={title} tabCt={setCt} />
<div class="view">
Content : {ct}
</div>
</div>
);
};
const TabButtons = (props) => {
return (
<>
{
props.tabName.map((item,i)=>
<button onClick={()=>props.tabCt(i)} className="btn">{item}</button>
) 
}

</>
);
};
export default MyTabsComponent;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

我不知道如何对任何数量的选项卡执行Rest我能处理——CSS,onClick事件我很了解,因为我很了解JS。

编辑:我找到一篇关于复合成分的文章https://blog.logrocket.com/understanding-react-compound-components/

他们说:

import React, { useState, createContext, useContext } from "react";
//the name of this context will be DataContext
const DataContext = createContext({});
function Tab({ id, children }) {
//extract the 'setActiveTabID` method from the DataContext state.
const [, setActiveTabID] = useContext(DataContext);
return (
<div>
<div onClick={() => setActiveTabID(id)}>{children}</div>
</div>
);
}
function TabPanel({ whenActive, children }) {
//get the 'activeTabID' state from DataContext.
const [activeTabID] = useContext(DataContext);
return <div>{activeTabID === whenActive ? children : null}</div>;
}
function TabSwitcher(props) {
const [activeTabID, setActiveTabID] = useState("a");
//since this component will provide data to the child components, we will use DataContext.Provider
return (
<DataContext.Provider value={[activeTabID, setActiveTabID]}>
{props.children}
</DataContext.Provider>
);
}
export default TabSwitcher;
export { Tab, TabPanel };

使用:

import TabSwitcher, { Tab, TabPanel } from "./TabSwitcher";
function App() {
return (
<div className="App">
<h1>TabSwitcher with Compound Components</h1>
<TabSwitcher>
<Tab id="a">
<button>a</button>
</Tab>
<Tab id="b">
<button>b</button>
</Tab>
<TabPanel whenActive="a">
<div>a panel</div>
</TabPanel>
<TabPanel whenActive="b">
<div>b panel</div>
</TabPanel>
</TabSwitcher>
</div>
);
}
export default App;

问题是:他们正在使用

TabPanel

作为一个容器,而我想要一个<div>

EDIT:请参阅Alexander在评论中发布的链接,了解类似选项卡的可访问性的最佳实践,或者这个链接有一个例子https://www.w3.org/TR/wai-aria-practices-1.1/examples/tabs/tabs-2/tabs.html

我在这里的帖子解决了";使得该工作";,但您确实应该以适当的tabtabpanel为目标,使其可访问。

原始答案:

问题是:他们使用TabPanel作为容器,而我想要<div>

当你说";我想要一个CCD_ 7";,你的意思是说你想在代码中写div,还是想在DOM中写一个div

您发现的示例中,他们使用TabPanel确实div渲染到DOM,因为TabPanel返回div。

突出的一点是,您不需要将标题存储在状态中,因为它们永远不会改变。

要做你想做的事,我可能会这样做:

import React,{useState} from "react";
const tabData = [
{title: "Section title 1", content: "Content of section 1"}
{title: "Section title 2", content: "Content of section 2"}
{title: "Section title 3", content: "Content of section 3"}
]
const MyTabsComponent = () => {
const [ct,setCt] = useState(null);
return (
<div className="tabs">
{tabData.map(({title}, i) => (
<TabButton
title={title}
isActive={i === ct}
onClick={()=>props.tabCt(i)} />
)}       
<div class="view">
Content : {tabData[ct].content}
</div>
</div>
);
};
const TabButton = ({ title, isActive, onClick }) => {
return (
<button onClick={onClick} className={isActive ? "active-btn" : "btn"}>
{title}
</button>
);
};
export default MyTabsComponent;

据我所知,您的问题是如何呈现任意数量的选项卡?您的代码片段似乎已经做到了这一点。然而,你确实有一个太多的括号,或者一个太少,这取决于你怎么看

import React,{useState} from "react";
const myTabs = ['Section 1','Section 2','Section 3'];
const MyTabsComponent = () => {
const [ct,setCt] = useState(null);
return (
<div className="tabs">
<TabButtons tabCt={setCt} />
<div>Content: {ct}</div>
</div>
);
};
const TabButtons = (props) => {
return (
<>
{myTabs.map((item,i) => (
<button onClick={()=>props.tabCt(i)} className="btn">
{item}
</button>
)}
</>
);
};
export default MyTabsComponent;

这应该行得通。myTabs中可以有1个或1000个选项卡,它将渲染所有选项卡。

最新更新