我是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
我在这里的帖子解决了";使得该工作";,但您确实应该以适当的tab
和tabpanel
为目标,使其可访问。
原始答案:
问题是:他们使用
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个选项卡,它将渲染所有选项卡。