गाय का I एक समस्या का सामना कर रहा है। मेरे पास 2-आयामी डेटा है। डेटा में एक नेस्टेड संरचना होती है जिसमें लिंक होते हैं।
const data = [
// First Div Panel
[
{
id: 1,
url: "/services",
title: "Services"
},
{
id: 2,
title: "Products",
children: [
{
id: 3,
url: "/themes-templates",
title: "Themes & Templates"
},
{
id: 4,
url: "/open-source",
title: "Open Source"
},
{
id: 5,
url: "/solutions",
title: "Solutions"
}
]
},
{
id: 6,
url: "/work",
title: "Work",
children: [
{
id: 7,
url: "/methodology",
title: "Methodology",
children: [
{
id: 8,
url: "/agile",
title: "Agile",
children: [
{
id: 9,
url: "/scrum",
title: "Scrum"
}
]
}
]
}
]
},
{
id: 10,
url: "/contact-us",
title: "Contact Us"
}
],
// Second Div Panel which contains children of second list item
[
{
id: 3,
url: "/themes-templates",
title: "Themes & Templates"
},
{
id: 4,
url: "/open-source",
title: "Open Source"
},
{
id: 5,
url: "/solutions",
title: "Solutions"
}
],
// Third Div Panel which contains children of third list item
[
{
id: 7,
url: "/methodology",
title: "Methodology",
children: [
{
id: 8,
url: "/agile",
title: "Agile",
children: [
{
id: 9,
url: "/scrum",
title: "Scrum"
}
]
}
]
}
],
// Fourth Div Panel contains the children of the 3rd sub list item
[
{
id: 8,
url: "/agile",
title: "Agile",
children: [
{
id: 9,
url: "/scrum",
title: "Scrum"
}
]
}
],
// Fourth Div Panel contains the children of the 3rd sub sub list item
[
{
id: 9,
url: "/scrum",
title: "Scrum"
}
]
];
मेरा कार्य उस 2-आयामी डेटा का उपयोग करना और एक मोबाइल मेनू बनाना react
है जिसमें एक पुश पैनल जैसी संरचना हो।
फिर भी, मैं इस तरह से बनाने की कोशिश करता हूं। मैंने जो किया वह मैंने हर उप-सरणी को एक अलग पैनल के रूप में माना है div
। सबसे पहले, उप-सरणी आइटम रूट पैनल पर विचार किया जाएगा जो डिफ़ॉल्ट रूप से दिखाई देता है। यदि किसी आइटम में कोई children
संपत्ति है तो इसका मतलब है next
कि उस सूची आइटम पर एक गतिशील बटन उत्पन्न होता है। जब हम इस बटन पर क्लिक करते हैं, तो यह is-visible
पैनल पर एक क्लास जोड़ देगा । लेकिन, सवाल यह है कि यह कैसे ट्रैक करेगा कि कौन सा पैनल उस बटन क्लिक से जुड़ा है ? मैं के साथ एक राज्य का उपयोग करने की कोशिश करता हूं activeId
और prevId
लेकिन मेरी अनुक्रमण सही ढंग से काम नहीं कर रहा है और एक सही पैनल नहीं खोल रहा है। आप क्रोम इंस्पेक्टर पैनल पर मेरे समाधान का निरीक्षण कर सकते हैं। मैं इसकी सराहना करता हूं यदि आप मुझे बताते हैं कि मैं क्या गलत कर रहा हूं?
कोड:
// Get a hook function
const {useState} = React;
//#region Data
const data = [
// First Div Panel
[
{
id: 1,
url: "/services",
title: "Services"
},
{
id: 2,
title: "Products",
children: [
{
id: 3,
url: "/themes-templates",
title: "Themes & Templates"
},
{
id: 4,
url: "/open-source",
title: "Open Source"
},
{
id: 5,
url: "/solutions",
title: "Solutions"
}
]
},
{
id: 6,
url: "/work",
title: "Work",
children: [
{
id: 7,
url: "/methodology",
title: "Methodology",
children: [
{
id: 8,
url: "/agile",
title: "Agile",
children: [
{
id: 9,
url: "/scrum",
title: "Scrum"
}
]
}
]
}
]
},
{
id: 10,
url: "/contact-us",
title: "Contact Us"
}
],
// Second Div Panel
[
{
id: 3,
url: "/themes-templates",
title: "Themes & Templates"
},
{
id: 4,
url: "/open-source",
title: "Open Source"
},
{
id: 5,
url: "/solutions",
title: "Solutions"
}
],
// Third Div Panel
[
{
id: 7,
url: "/methodology",
title: "Methodology",
children: [
{
id: 8,
url: "/agile",
title: "Agile",
children: [
{
id: 9,
url: "/scrum",
title: "Scrum"
}
]
}
]
}
],
// Fourth Div Panel
[
{
id: 8,
url: "/agile",
title: "Agile",
children: [
{
id: 9,
url: "/scrum",
title: "Scrum"
}
]
}
],
// Fifth Div Panel
[
{
id: 9,
url: "/scrum",
title: "Scrum"
}
]
];
//#endregion Data
//#region Component
const PanelMenu = props => {
const { title } = props;
const [items, setItems] = useState(data);
// Title Header of the Panel
const [headerTitle, setHeaderTitle] = useState(title ? title : "");
// Previous Title Header of the Panel
const [prevHeaderTitle, setPrevHeaderTitle] = useState(title ? title : "");
// ActiveIndex => 0 means by default master-panel is active
const [activeId, setActiveId] = useState(0);
// PreviousIndex
const [prevId, setPrevId] = useState(0);
const handlePanelBtn = (newTitle, index, prevIndex) => {
// Title Checking
const titleProp = title ? title : "";
const prevTitle = index === 0 ? titleProp : headerTitle;
// SetStates
setPrevHeaderTitle(prevTitle);
setHeaderTitle(newTitle);
setActiveId(index);
setPrevId(prevIndex);
};
const panelRenderer = () => {
const panelsJSX = [];
for (let i = 0; i < items.length; i++) {
let childItemIndex = i;
const panels = (
<div
key={i}
id={i === 0 ? "p__master" : `p__student-${i}`}
className={
childItemIndex === activeId
? "p__panel is-visible"
: "p__panel is-hide"
}
>
<ul>
{items[i].map((item, index) => {
// It means it have children
if (item.children && item.children.length > 0) {
childItemIndex++;
return (
<li key={item.id} className="p-next">
{item.url ? (
<a href={item.url} className="p-link">
{item.title}
</a>
) : (
<div className="p-link">{item.title}</div>
)}
<button
type="button"
className="p-next__btn"
data-id={`#p__student-${childItemIndex}`}
onClick={() => handlePanelBtn(item.title, index, prevId)}
>
<span>></span>
</button>
</li>
);
} else {
return (
<li key={item.id}>
<a href={item.url} className="p-link">
{item.title}
</a>
</li>
);
}
})}
</ul>
</div>
);
panelsJSX.push(panels);
}
return panelsJSX;
};
const renderer = () => {
if (items && items.length > 0) {
return (
<div className="p">
<div className="p__wrap">
{/* Panel Actions => Header */}
<div className="p__actions">
{/* Previous Button */}
{activeId !== 0 && (
<button
type="button"
className="p-action__btn left"
onClick={() =>
handlePanelBtn(prevHeaderTitle, prevId, prevId)
}
>
<span><</span>
</button>
)}
{/* Title */}
{headerTitle && (
<div className="p-action__title">{headerTitle}</div>
)}
{/* Close Button */}
<button type="button" className="p-action__btn right">
<span>×</span>
</button>
</div>
{/* Panel children Wrapper */}
<div className="p__children">{panelRenderer()}</div>
</div>
</div>
);
}
};
return <React.Fragment>{renderer()}</React.Fragment>;
};
//#endregion Component
// Render it
ReactDOM.render(
<PanelMenu title="Menu" />,
document.getElementById("root")
)
<style>
*,:before,:after {
box-sizing: border-box;
}
.p__wrap {
position: absolute;
top: 0;
bottom: 0;
left: 0;
width: 320px;
background-color: #fff;
box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
z-index: 1;
color: #333;
overflow-x: hidden;
}
.p__actions {
position: relative;
padding: 14px;
min-height: 54px;
border-bottom: 1px solid #dcdcdc;
}
.p-action__title {
text-align: center;
color: #333;
text-transform: uppercase;
font-weight: 700;
}
.p-action__btn {
position: absolute;
width: 54px;
height: 54px;
top: 0;
right: 0;
font-size: 16px;
color: #333;
border: none;
cursor: pointer;
}
.left {
left: 0;
}
.right {
right: 0;
}
.p__children {
position: relative;
background-color: #fff;
overflow: hidden;
height: calc(100% - 54px);
}
.p__panel {
overflow-x: hidden;
overflow-y: auto;
position: absolute;
transform: translateX(100%);
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 0;
transition: transform 0.2s ease 0s;
}
.p__panel.is-visible {
transform: translateX(0);
z-index: 1;
}
.p__panel.is-hide {
opacity: 0;
visibility: hidden;
}
.p__panel > ul {
margin: 0;
padding: 0;
}
.p__panel > ul > li {
list-style: none;
border-bottom: 1px solid #dcdcdc;
}
.p__panel > ul > li > .p-link {
color: #333;
display: block;
line-height: 22px;
font-size: 14px;
padding: 14px 24px;
background-color: transparent;
cursor: pointer;
}
.p__panel > ul > li > .p-link:hover {
background-color: #dcdcdc;
}
.p-next {
position: relative;
}
.p-next__btn {
position: absolute;
padding: 14px 16px;
font-size: 16px;
line-height: 22px;
top: 0;
right: 0;
background-color: rgb(240,240,240);
color: #333;
border: none;
border-left: 1px solid #dcdcdc;
cursor: pointer;
}
</style>
<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>
<div id="root"></div>