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.