我想要实现的是通过过渡动画改变不透明度,以获得改变可见元素的平滑效果。
我构建的组件是Slider。虽然下一张幻灯片的幻灯片不透明度正在变为1,但当前幻灯片的更改为0。
我的第一个幻灯片组件版本
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/>
)
}
}
我的第一个想法是将当前幻灯片索引存储在状态中。所以我的Slides容器知道哪个幻灯片是最新的,并将其活动属性更改为true。但这会影响重新渲染此幻灯片并且转换不可见。第一个问题:为什么?
我最终玩了反应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的使用。
答案 0 :(得分:1)
编辑:原来OP正在使用Styled Components,并且每次调用render()
时都会创建一个新组件,因为const Wrapper...
位于其中render()
方法。
这导致Wrapper
组件每次更新Slide
组件时重新安装,因此不会发生任何CSS转换,因为它是组件的新实例,因此是新的HTML元素。
这里有一个概念证明,即使active
状态作为道具传递,并且没有外部CSS来控制UI状态,CSS转换仍然有效:CodePen。我使用了相同的更改不透明度的示例,并在活动幻灯片之间切换以显示其有效。
如果您的状态发生变化时Slide
重新呈现,则必须有其他可能重新呈现整个序列的内容。也许您的组件正在被删除并重新添加,或其他内容。您需要自己调试,或提供更多代码,以便我们为您提供帮助。
或者,如评论中所述,如果您需要,可以使用ReactCSSTransitionGroup。