Skip to content
Advertisement

Custom slider component in React is not working as expected

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:

  1. After showing the last card I want arrow for next to not be clickable;
  2. 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.

User contributions licensed under: CC BY-SA
7 People found this is helpful
Advertisement