在React中,我们怎么样使用它跟CSS 3 动画结合在一起使用呢?
CSS3 Transitoin
CSS3动画要求DOM属性变化的时候才能够被触发。所以这就需要我们把属性变化后的React元素渲染到真实的DOM中,这样才能够有过渡效果,形成动画。
那我们来实现一种:第一次渲染后,当渲染完成时,调用setState(),且重新设置样式,接着便触发第二次渲染,中间便有过渡效果。
注意:使用window.getComputedStyle(),调用它,会刷新DOM的样式,确保的是之前设置的样式已经渲染到DOM中。
如下例子:
我们实现由图1到图2的过渡动画,代码如下
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>动画 : CSS3 Transition</title>
<script src="lib/react.min.js"></script>
<script src="lib/JSXTransformer.js"></script>
<!--组件样式-->
<style>
.ez-gauge{
position:relative;
display:inline-block;
}
.ez-gauge .pointer{
position : absolute;
left : 149px;
top : 104px;
transform-origin : 1px 45px;
transition : transform 2s;
}
</style>
</head>
<body>
<div id="content"></div>
<script type = "text/jsx">
//组件定义
var EzGaugeComp = React.createClass({
//声明初始状态
getInitialState : function(){
return {
value : 0, //速度值
mounted : false //是否已挂接到DOM
};
},
//首次渲染后改变状态
componentDidMount : function(){
this.setState({mounted : true});
},
//校验属性值,无效时不刷新界面
shouldComponentUpdate : function(nextProps,nextState){
if(nextProps.value > 220 || nextProps.value<0) return false;
return true;
},
render : function(){
//速度为0时的旋转角度
var degree = -201;
//根据属性值计算旋转角度
if(this.state.mounted){
degree = (this.props.value / 220) * 265 - 201;
//确保之前设置的样式生效
window.getComputedStyle(React.findDOMNode(this.refs.ptr)).transform;
}
//表针样式
var style={
transform : "rotate("+degree+"deg)"
};
return (
<div className="ez-gauge">
<img src="img/gauge.jpg" />
<img src="img/gauge-pointer.jpg" className="pointer" style={style} ref="ptr"/>
</div>
);
}
});
//渲染
React.render(
<EzGaugeComp value="200"/>,
document.querySelector("#content"));
</script>
</body>
</html>
再提一次,window.getComputedStyle()是更新样式
默认属性
比如我们的React组件渲染了很多个,而如果我们为每一个都要设置value:0的属性,那么需要重复去声明,太麻烦了。
那React也为我们提供了组件的默认属性。
在声明组件的时候,用getDefaultProps()方法声明:(类比getInitialState吧)
var EzDemoComp = React.createClass({
//设置默认属性值
getDefaultProps:function(){
return {
value : 0
}
},
render: function(){
//使用this.props.value访问属性,如果用户没有设置,则该值为默认值
return <div classname="ez-demo">{this.props.value}</div>;
}
});
//创建React元素时没有指定属性值
React.render(<ezdemocomp></ezdemocomp>,
document.querySelector("#content"));
当然,如果我们在render中的<ezdemocomp>中声明了value,则会覆盖默认属性,如<ezdemocomp value="1"></ezdemocomp>