I am trying to improve my skills in React here and I wanted to build my portfolio, so I decided to have custom slider instead of using a library, so I use the following code:
const ProjectWrapper = styled.div`
.container {
transform: translateX(-${(props) => props.activeIndex * 200}px);
transition: transform 0.3s;
display: flex;
flex-direction: column;
margin: 20px;
border: 1px solid gray;
border-radius: 5px;
padding: 20px;
text-align: justify;
color: white;
text-decoration: none;
height: 450px;
}
`;
export default function Portfolio() {
const [activeIndex, setActiveIndex] = useState(0);
const updateIndex = (newIndex) => {
if (newIndex < 0) {
newIndex = projects.count - 1;
} else if (newIndex >= projects.count) {
newIndex = 0;
}
setActiveIndex(newIndex);
};
return (
<div>
<Arrow>
<ProjectWrapper activeIndex={activeIndex}>
{projects.map((el, idx) => {
return (
<a key={idx} className="container" href={el.url}>
<div>
<div className="img">
<img src={el.image} alt={el.title} />
</div>
<div className="row">
<h3 className="title">
{el.title}
<a target="_blank" href={el.github}>
{el.github === "" ? (
""
) : (
<i className="fa-brands fa-github fa-lg"></i>
)}
</a>
</h3>
<div className="desc">
<p>{el.description}</p>
</div>
<p>
<b>Technologies:</b> {el.resources}
</p>
</div>
</div>
</a>
);
})}
</ProjectWrapper>
<button
onClick={() => {
updateIndex(activeIndex - 1);
}}
>
{" "}
<i class="fa-solid fa-angle-left"></i>
</button>
<button
onClick={() => {
updateIndex(activeIndex + 1);
}}
>
<i class="fa-solid fa-angle-right"></i>
</button>
</Arrow>
</div>
);
}
It is working pretty fine except for two issues:
- After showing the last card I want arrow for next to not be clickable;
- After going next, and then clicking back to the very beginning, the arror for next is not clickable anymore. After refreshing the page, I am able again to go to the next cards.
Anyone any idea what can I improve on my code here?
Advertisement
Answer
To disable the “Next” button, add a conditional disabled
flag to it. This example will disable the button when the state is equal to the total number of projects:
<button
onClick={() => {
updateIndex(activeIndex + 1);
}}
disabled={activeIndex === (projects.count - 1)}
/>
For your second problem, your function is currently setting the index to 0 once you reach the last slide. So you are on slide 5/5, but your function is setting the index to 0:
else if (newIndex >= projects.count) {
newIndex = 0;
}
This is muddling the logic, so I would recommend removing updateIndex()
entirely and writing your buttons like so:
<button
onClick={() => setActiveIndex((prevIndex) => prevIndex + 1)}
>
<i class="fa-solid fa-angle-right"></i>
</button>
Or – 1 for the back button.