【问题标题】:Change component props with transition使用过渡更改组件道具
【发布时间】:2017-02-14 07:03:06
【问题描述】:

我想要实现的是通过过渡动画改变不透明度,以获得改变可见元素的平滑效果。

我构建的组件是 Slider。在更改下一张幻灯片的幻灯片不透明度时,当前幻灯片将更改为 1 和 0。

我的第一个 Slide 组件版本

 export class Slide extends React.PureComponent {
   render() {
    let { img, backgroundColor, active, ...props } = this.props;
    const Wrapper = styled.div`
      background-image: url(${img});
      background-color: ${backgroundColor};
      background-size: cover;
      background-position: 50% 50%;
      opacity: ${active ? 1 : 0};
      transition: opacity 1s;
    `;
    return (
      <Wrapper/>
    )
  }
}

我的第一个想法是将当前幻灯片索引存储在状态中。所以我的幻灯片容器知道哪张幻灯片是当前的,并将其活动属性更改为 true。但这会影响重新渲染此幻灯片,并且过渡不可见。第一个问题:为什么?

我最终玩起了 react dom,并手动更改了当前元素的不透明度。

export default class Slider extends Component {
  __slidesCount;
  __current;
  __refs = [];

  constructor(props) {
    super(props);
    this.__current = 0;
    this.__slidesCount = this.props.children.length
  }

  componentWillMount() {
    // Save number of slides
  }

  nextSlide = () => {
    let next = this.__current < this.__slidesCount - 1 ? this.__current + 1 : 0,
      nextSlide = this.__refs[next],
      currentSlide = this.__refs[this.__current];

    ReactDOM.findDOMNode(nextSlide).style['opacity'] = 1;
    ReactDOM.findDOMNode(currentSlide).style['opacity'] = 0;
    this.__current = next;
    setTimeout(this.nextSlide, 3000)
  };

  componentDidMount() {
    // set timeout to run it after component mounting is finished
    setTimeout(() => {
      ReactDOM.findDOMNode(this.__refs[0]).style['opacity'] = 1;
    }, 0);
    // call function changing slide to next
    setTimeout(this.nextSlide, 3000)
  }

  render() {
    let { children, ...props } = this.props;
    let slides = children.map((slide, index) => {
      return React.cloneElement(slide, { ref: ref => this.__refs.push(ref) })
    });
    return (
      <SlidesWrapper {...props}>
        {slides}
      </SlidesWrapper>
    )
  }
}

您如何看待这个解决方案?有什么方法可以更容易吗? 当然,我不想使用 jQuery 并尽量减少外部 css 的使用。

【问题讨论】:

  • 你试过 ReactCSSTransitionGroup 吗?
  • 我读到的关于ReactCSSTransitionGroup 的内容是它用于新元素或已卸载的元素。 ReactCSSTransitionGroup is a high-level API based on ReactTransitionGroup and is an easy way to perform CSS transitions and animations when a React component enters or leaves the DOMfacebook.github.io/react/docs/animation.html

标签: javascript reactjs css-transitions


【解决方案1】:

编辑:原来OP使用Styled Components,每次调用render()时他都在创建一个新组件,因为const Wrapper...位于render()方法内部.

这会导致每次更新Slide 组件时都会重新安装Wrapper 组件,因此不会发生任何CSS 转换,因为它是组件的新实例,因此完全是一个新的HTML 元素。


这是一个概念证明,即使 active 状态作为道具传递,并且没有外部 CSS 来控制 UI 状态,CSS 转换仍然有效:CodePen。我使用了相同的示例来更改不透明度并在活动幻灯片之间切换以显示它有效。

如果您的Slides 在您的状态更改时重新渲染,则必须有其他东西可能会重新渲染整个序列。也许您的组件正在被删除并再次重新添加,或者其他什么。您需要自己调试,或提供更多代码以便我们为您提供帮助。

或者,如 cmets 中所述,如果您发现需要,可以使用 ReactCSSTransitionGroup

【讨论】:

  • 好的,我想我知道为什么它对我不起作用了。我对其进行了测试,如果我的幻灯片是简单的 div,它就可以工作。但如果它返回 styled.div 它没有。似乎它重新渲染了整个 div 而只是改变了组件的样式。
  • 很高兴听到。我很好奇,styled.div 是什么语法?我以前从未见过。
  • 这是来自 styled-components 库的组件 - github.com/styled-components/styled-components
  • 我的错误是在每个渲染方法中都创建了新的styled 组件。每次调用幻灯片渲染时都是不同的对象。
  • 好的,我明白了!我会为可能遇到此问题的其他人更新答案。
猜你喜欢
  • 2020-02-27
  • 2020-11-10
  • 2021-08-12
  • 1970-01-01
  • 1970-01-01
  • 2018-05-09
  • 2021-11-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多