如何在 React 中同时设置 display:block 和过渡不透明度?
How to set display:block and transition opacity at the same time in React?
我在 JSX 中定义了一个背景层元素,它最初设置了 display:none
:
<div id="naviBG" style={naviBGStyleClone} role="button" onClick={this.onCloseClicked} />
风格:
const naviBGStyle = {
display: 'none',
opacity: 0,
transition: 'opacity 0.4s ease',
};
单击时,我希望图层使用 css 中定义的过渡平滑消失或重新出现。在 render()
中,我检查元素是应该显示还是隐藏:
渲染()
const naviBGStyleClone = Object.assign({}, naviBGStyle);
if (this.props.status === 'closed') {
naviBGStyleClone.display = 'none';
naviBGStyleClone.opacity = 0;
} else {
naviBGStyleClone.display = 'block';
naviBGStyleClone.opacity = 1;
}
return (
<div id="naviBG" style={naviBGStyleClone} role="button" onClick={this.onCloseClicked} />
);
现在,这个有点像元素 shown/hidden 但它弹出时没有设置不透明度的过渡动画。
通常我会使用类似 requestAnimationFrame
的方法来解决这个问题:
render() 与 raf:
const naviBGStyleClone = Object.assign({}, naviBGStyle);
if (this.props.status === 'closed') {
naviBGStyleClone.display = 'none';
if (typeof window !== 'undefined') {
window.requestAnimationFrame(() => {
naviBGStyleClone.opacity = 0;
});
}
} else {
naviBGStyleClone.display = 'block';
if (typeof window !== 'undefined') {
window.requestAnimationFrame(() => {
naviBGStyleClone.opacity = 1;
});
}
}
return (
<div id="naviBG" style={naviBGStyleClone} role="button" onClick={this.onCloseClicked} />
);
但这在 React 中不起作用,因为它会导致样式在 render()
已经完成后被修改。
那么,在 React 中执行此操作的正确方法是什么?
因为转换不会在通过 display: none
隐藏的项目上触发,您可以连续调用 setState
两次,一次触发显示更改,然后再次触发不透明度更改,并且以相反的顺序相同,使其淡出然后隐藏。
class App extends React.Component {
state = { display: 'none', opacity: 0 }
toggle = () => {
if (this.state.display === 'none') {
this.setState({ display: 'block' })
setTimeout(() =>
this.setState({ opacity: 1 }), 10 // something very short
)
}
if (this.state.display === 'block') {
this.setState({ opacity: 0 })
setTimeout(() =>
this.setState({ display: 'none' }), 300 // same as transition time
)
}
}
render() {
return (
<div>
<button onClick={this.toggle}>toggle</button>
<div
style={{
transition: 'opacity 0.3s ease',
opacity: this.state.opacity,
display: this.state.display
}}
/>
</div>
)
}
}
我也鼓励你看看 React Motion 来处理更复杂的过渡,就像你可能用 requestAnimationFrame
我在 JSX 中定义了一个背景层元素,它最初设置了 display:none
:
<div id="naviBG" style={naviBGStyleClone} role="button" onClick={this.onCloseClicked} />
风格:
const naviBGStyle = {
display: 'none',
opacity: 0,
transition: 'opacity 0.4s ease',
};
单击时,我希望图层使用 css 中定义的过渡平滑消失或重新出现。在 render()
中,我检查元素是应该显示还是隐藏:
渲染()
const naviBGStyleClone = Object.assign({}, naviBGStyle);
if (this.props.status === 'closed') {
naviBGStyleClone.display = 'none';
naviBGStyleClone.opacity = 0;
} else {
naviBGStyleClone.display = 'block';
naviBGStyleClone.opacity = 1;
}
return (
<div id="naviBG" style={naviBGStyleClone} role="button" onClick={this.onCloseClicked} />
);
现在,这个有点像元素 shown/hidden 但它弹出时没有设置不透明度的过渡动画。
通常我会使用类似 requestAnimationFrame
的方法来解决这个问题:
render() 与 raf:
const naviBGStyleClone = Object.assign({}, naviBGStyle);
if (this.props.status === 'closed') {
naviBGStyleClone.display = 'none';
if (typeof window !== 'undefined') {
window.requestAnimationFrame(() => {
naviBGStyleClone.opacity = 0;
});
}
} else {
naviBGStyleClone.display = 'block';
if (typeof window !== 'undefined') {
window.requestAnimationFrame(() => {
naviBGStyleClone.opacity = 1;
});
}
}
return (
<div id="naviBG" style={naviBGStyleClone} role="button" onClick={this.onCloseClicked} />
);
但这在 React 中不起作用,因为它会导致样式在 render()
已经完成后被修改。
那么,在 React 中执行此操作的正确方法是什么?
因为转换不会在通过 display: none
隐藏的项目上触发,您可以连续调用 setState
两次,一次触发显示更改,然后再次触发不透明度更改,并且以相反的顺序相同,使其淡出然后隐藏。
class App extends React.Component {
state = { display: 'none', opacity: 0 }
toggle = () => {
if (this.state.display === 'none') {
this.setState({ display: 'block' })
setTimeout(() =>
this.setState({ opacity: 1 }), 10 // something very short
)
}
if (this.state.display === 'block') {
this.setState({ opacity: 0 })
setTimeout(() =>
this.setState({ display: 'none' }), 300 // same as transition time
)
}
}
render() {
return (
<div>
<button onClick={this.toggle}>toggle</button>
<div
style={{
transition: 'opacity 0.3s ease',
opacity: this.state.opacity,
display: this.state.display
}}
/>
</div>
)
}
}
我也鼓励你看看 React Motion 来处理更复杂的过渡,就像你可能用 requestAnimationFrame