admin管理员组文章数量:1430000
I have a background layer element defined in JSX which has set display:none
intially:
<div id="naviBG" style={naviBGStyleClone} role="button" onClick={this.onCloseClicked} />
Style:
const naviBGStyle = {
display: 'none',
opacity: 0,
transition: 'opacity 0.4s ease',
};
When clicked, I want the layer to smoothly disappear or re-appear using the transition defined in css. In render()
I check if the element should be shown or hidden:
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} />
);
Now, this kinda works as the element will be shown/hidden but it pops in without the transition animation set on opacity.
Normally I would then use something like requestAnimationFrame
to work around this like so:
render() with 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} />
);
But this won't work in react as it would cause the style to be modified after render()
has already finished.
So, what's the correct way to do this in React?
I have a background layer element defined in JSX which has set display:none
intially:
<div id="naviBG" style={naviBGStyleClone} role="button" onClick={this.onCloseClicked} />
Style:
const naviBGStyle = {
display: 'none',
opacity: 0,
transition: 'opacity 0.4s ease',
};
When clicked, I want the layer to smoothly disappear or re-appear using the transition defined in css. In render()
I check if the element should be shown or hidden:
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} />
);
Now, this kinda works as the element will be shown/hidden but it pops in without the transition animation set on opacity.
Normally I would then use something like requestAnimationFrame
to work around this like so:
render() with 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} />
);
But this won't work in react as it would cause the style to be modified after render()
has already finished.
So, what's the correct way to do this in React?
Share Improve this question asked Jun 6, 2017 at 14:02 Timo ErnstTimo Ernst 16k25 gold badges115 silver badges174 bronze badges 6- the most mon way to do this is doing it in two quick steps. set the display to block then on the next loop change the opacity. Is display block even a requirement though? what about changing the zindex instead? – azium Commented Jun 6, 2017 at 14:25
-
Yeah, I think it would be nice if the element pletely disappears from the render tree using
display:none
. What do you mean by "next loop"? – Timo Ernst Commented Jun 6, 2017 at 17:17 - Next cycle of the event loop. If you trigger a css transition on an element with display none then the transition doesn't occur. if you set it to block then on the very next round of the event loop trigger the transition then it will happen. This is true with or without react. I can write up an answer with some examples if you want. My above suggestion is not the only way – azium Commented Jun 6, 2017 at 18:10
- @azium That's why I used requestAnimationFrame - Doesn't work – Timo Ernst Commented Jun 6, 2017 at 18:52
- requestAnimationFrame can be used, just not the way you have it. I'll write up an answer with some working examples – azium Commented Jun 6, 2017 at 18:57
1 Answer
Reset to default 4Because transitions don't trigger on items that are hidden via display: none
, you can call setState
twice in a row, once to trigger the display change then again to trigger the opacity change, and the same in the reverse order to make it fade out then hidden.
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>
)
}
}
Example on codepen
I would also encourage you to look at React Motion for handling more intricate transitions like you might do with requestAnimationFrame
https://github./chenglou/react-motion
本文标签: javascriptHow to set displayblock and transition opacity at the same time in ReactStack Overflow
版权声明:本文标题:javascript - How to set display:block and transition opacity at the same time in React? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1745552263a2662996.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论