当用户单击它时,我想制作一个很酷的框增长动画(展开),我想通过以下方式做到这一点:
expanded
状态变量,并将div的position
更改为fixed
,还更改了left, top
值和width, height
css值我的问题是在最初的div扩展点击中。似乎两个状态的更改都在一个周期内呈现,因此我在第一次展开点击时看不到平滑的动画。我尝试通过setState
回调来完成此操作,还尝试在div尺寸处于状态后通过expanded
方法更新componentDidUpdate
,除了通过{设置expanded
{1}}。
通过setTimeout
回调的代码示例
setState
如何从Charts中实现该样式在更改基于扩展值的类之前会渲染比例?我既不想使用setTimeout也不想在onScroll事件等中更新所有图表比例。
答案 0 :(得分:3)
您只需要向setState传递一个函数而不是一个对象,以确保按顺序应用状态更改:
this.setState(previousState => ({
previousChange: "value"
}))
this.setState(previousState => ({
afterPreviousChange: previousState.previousChange
}))
https://reactjs.org/docs/react-component.html#setstate
另一种选择是将回调传递给setState,该回调在应用状态更改后运行,例如:
this.setState({ someChange: "value" }, () => this.setState({
otherChange: "value"
}))
CSS过渡也可以帮上忙。
答案 1 :(得分:1)
使用React状态为属性设置动画不是正确的方法。状态更新总是会批量处理,您通常不希望每秒重新渲染整个组件60次
在您的状态下存储'expanded'布尔值,并相应地更改element的类。使用CSS在两个状态之间添加动画
handleClick = () => {
this.setState({ expanded: !this.state.expanded })
}
render() {
return (
<div
className={`box ${this.state.expanded ? 'expanded' : ''}`}
onCLick={this.handleClick}
/>
)
}
在您的CSS中
.box {
width: 100px;
height: 100px;
transition: width 2s;
}
.expanded {
width: 300px;
}
根据评论添加:
您想要做的是:
position: fixed
设置为您的元素。这将立即将其捕捉到屏幕顶部,因此您需要选择右上和左值,以便固定位置从静态位置开始(默认)。为此,您可以使用element.getBoundingClientRect() top
和left
属性,这些属性将使您的元素出现在屏幕中间,并应用它们。setTimeout
中,以确保浏览器使用在第1阶段应用的样式至少渲染一次。粗略的工作示例:
class Example extends React.Component {
constructor(props) {
super(props)
this.state = {
expanded: false,
style: {}
}
}
handleClick = (e) => {
if (!this.state.expanded) {
const r = e.target.getBoundingClientRect()
const style = {
top: r.y,
left: r.x,
}
this.setState({
expanded: !this.state.expanded,
style
})
setTimeout(() => {
this.setState({
style: {
top: (window.innerHeight / 2) - 50,
left: (window.innerWidth / 2) - 50,
}
})
})
} else {
this.setState({
expanded: false,
style: {}
})
}
}
render() {
return (
<div className={'container'}>
<div className={'empty'} />
<div className={'empty'} />
<div className={'empty'} />
<div
onClick={this.handleClick}
className={`box ${this.state.expanded ? 'expanded' : ''}`}
style={this.state.style}
/>
</div>
)
}
}
和styles.css
* {
box-sizing: border-box;
padding: 0;
margin: 0;
}
.container {
height: 200vh;
}
.empty {
height: 100px;
width: 100px;
border: 1px solid gray;
}
.box {
height: 100px;
width: 100px;
border: 3px solid red;
transition: all 0.5s;
}
.expanded {
position: fixed;
}