i just started with React and Next.js and I'm messing around with hooks and i got stuck, i created a vertical menu, i want to display the content below each title, but only one at a time taking in mind these 2 options:
Thank you so much for your time.
I made a sandbox of the basic logic of my code: https://codesandbox.io/s/affectionate-morning-tyj8j?file=/src/App.tsx
That same code is this:
import {useState} from "react";
export default function Test() {
const [content1, setContent1] = useState(null);
const [content2, setContent2] = useState(null);
const [content3, setContent3] = useState(null);
return (
<div>
<div onClick={() => setContent1(Content_1)}>
Click to show content 1
<div>
{content1}
</div>
</div>
<div onClick={() => setContent2(Content_2)}>
Click to show content 2
<div>
{content2}
</div>
</div>
<div onClick={() => setContent3(Content_3)}>
Click to show content 3
<div>
{content3}
</div>
</div>
</div>
)
}
const Content_1 = () => {
return (
<p>Content 1</p>
)
}
const Content_2 = () => {
return (
<p>Content 2</p>
)
}
const Content_3 = () => {
return (
<p>Content 3</p>
)
}
I used the same structure to be easier for you to understand :) If you still have difficulties, keep me in touch.
import React, { useState } from 'react';
export default function Test() {
// states
const [content1, setContent1] = useState(true);
const [content2, setContent2] = useState(false);
const [content3, setContent3] = useState(false);
// content
const Content_1 = <p>Content 1</p>;
const Content_2 = <p>Content 2</p>;
const Content_3 = <p>Content 3</p>;
function setContent(id) {
setContent1(id === 1);
setContent2(id === 2);
setContent3(id === 3);
}
return (
<div>
<button onClick={() => setContent(1)}>Show 1</button>
<button onClick={() => setContent(2)}>Show 2</button>
<button onClick={() => setContent(3)}>Show 3</button>
{content1 && <div>{Content_1}</div>}
{content2 && <div>{Content_2}</div>}
{content3 && <div>{Content_3}</div>}
</div>
);
}
You should take a step back and think a bit more abstractly about what your UI interaction means.
- if i click a title which content is already displayed, the content will just hide.
- if i click a different title, the content of the last title will hide and the content of the new title will appear below it.
So effectively you only ever have one content section open/visible at-a-time. There is no need to store individual states for each content section you want to manually toggle, and as the number of content sections grows you'll need to increase number of toggles linearly. This is a terribly inefficient way to scale.
I suggest using a single state to hold which content section is active. Use a toggle handler to either toggle back "closed" a section if its id is set again, otherwise set a new section id. Conditionally render the section if its id matches the active id set in state.
function App() {
const [active, setActive] = useState<number>(-1);
const toggleHandler = (id: number) => () =>
setActive((active) => (active === id ? -1 : id));
return (
<div>
<div onClick={toggleHandler(1)}>
Click to show content 1{active === 1 && <Content1 />}
</div>
<div onClick={toggleHandler(2)}>
Click to show content 2{active === 2 && <Content2 />}
</div>
<div onClick={toggleHandler(3)}>
Click to show content 3{active === 3 && <Content2 />}
</div>
</div>
);
}