You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ReactJS轮播组件滑动动画实现求助:从零构建后无法添加动画

Hey there! Let's break this down step by step since you're new to React and animations—no fancy libraries required to get this working. First, let's fix a critical issue in your code that might be causing unexpected behavior, then add the slide animations.

Fix First: Remove setState in Render

First off, you've got a big issue here—never call this.setState() inside the render() method! Render should be a pure function that just returns JSX based on your state/props, no side effects. Those setState calls in your render are causing unnecessary re-renders and buggy behavior. Let's move that boundary logic into your changePositionNext and changePositionPrev methods instead.

Step 1: Update Position Logic

Let's fix the boundary checks so they work correctly even when your jobs list isn't a multiple of 3:

changePositionNext() {
  const { jobs, position } = this.state;
  const maxPosition = Math.max(0, jobs.length - 3); // Prevent negative positions

  if (jobs.length <= 3) return; // No need to slide if we have 3 or fewer cards

  const newPosition = position >= maxPosition ? 0 : position + 3;
  this.setState({ position: newPosition });
}

changePositionPrev() {
  const { jobs, position } = this.state;
  const maxPosition = Math.max(0, jobs.length - 3);

  if (jobs.length <= 3) return;

  const newPosition = position <= 0 ? maxPosition : position - 3;
  this.setState({ position: newPosition });
}

This ensures we never set a position that would slice beyond the jobs array or go negative.

Step 2: Add Slide Animation with CSS

Since you're new to animations, let's use pure CSS transitions—they're straightforward and don't require any extra libraries. Here's how to adjust your JSX and SCSS:

Updated JSX Render

We'll add a slide_wrapper div around all your job cards. This wrapper will be the element we animate using transform: translateX:

render() {
  const { jobs, position } = this.state;
  
  // Calculate slide offset: each "page" of 3 cards shifts the wrapper by 1/3 of its width
  const slidePercentage = -(position / jobs.length) * 100;

  return (
    <div className='main_container' id='job'>
      <BlocSection 
        section_title={"Nos offres d'emploi"} 
        section_intro={'Lorem ipsum dolor sit amet consectetur, adipisicing elit. Sequi alias iste ducimus tenetur saepe reprehenderit quasi reiciendis ab architecto.'} 
      />
      <div className='slider_container'>
        <div onClick={() => this.changePositionPrev()} className="arrow_container">
          <img src={back} alt="Previous" className="arrow"/>
        </div>
        <div className="card_container">
          {/* Wrapper to handle sliding animation */}
          <div 
            className="slide_wrapper"
            style={{ transform: `translateX(${slidePercentage}%)` }}
          >
            {jobs.map(job => {
              const title = job.title.rendered;
              const description = job.acf.job_description;
              const lien = job.acf.job_linkedin_url;
              return(
                <JobCard key={title} title={title} description={description} lien={lien} />
              );
            })}
          </div>
        </div>
        <div onClick={() => this.changePositionNext()} className="arrow_container">
          <img src={next} alt="Next" className="arrow"/>
        </div>
      </div>
    </div>
  );
}

Note: We're mapping all jobs instead of just selected now—this lets the wrapper contain every card, so the slide animation can smoothly move them in and out of view. The card_container will hide anything outside its bounds.

Updated SCSS

Add these styles to your Carousel.scss:

.card_container {
  overflow: hidden; // Hide cards outside the visible area
  width: 100%;
}

.slide_wrapper {
  display: flex;
  transition: transform 0.5s ease-in-out; // Smooth 0.5-second slide animation
  width: fit-content; // Let the wrapper grow to fit all cards
}

// Ensure each JobCard takes up exactly 1/3 of the container width
.JobCard {
  flex: 0 0 calc(100% / 3);
  box-sizing: border-box;
  padding: 0 1rem; // Optional spacing between cards
}

How This Works

  • When position changes, the slide_wrapper's transform: translateX value updates automatically.
  • CSS handles the smooth animation of this change over 0.5 seconds (you can adjust the duration by changing 0.5s).
  • The card_container keeps only 3 cards visible at a time, hiding the rest.

Why Your Earlier CSS Class Attempt Failed

Chances are, you were toggling classes without syncing them properly with React's state cycle. React needs to re-render when state changes to apply new styles—this method uses state directly to drive the animation, so it stays in sync with React's update process.

Key Takeaways for React Animations

  • Never setState in render: It causes infinite loops and unpredictable behavior.
  • Start with CSS transitions: They're easier to learn than animation libraries when you're new to React.
  • State drives UI changes: Let React state updates trigger your animations instead of trying to manually manipulate DOM classes.

You've already got the core carousel logic down—great work! The animation part just needed a small adjustment to how you structure the DOM and link state to styles.

内容的提问来源于stack exchange,提问作者Maëlle

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 09:17:34