javascript - 使用 SCSS 在 React 中添加 div 淡出和 div 的条件渲染
问题描述
我目前div
使用 SCSS/SASSmixin
和keyframes
.
我还想div
在它关闭后添加淡出功能。我尝试动态更改 div ( className={div_enable?"div_in":"div_out"}
) 的类,但问题是,将条件渲染更改为false
/dismisses 的事件(在下面的示例中,当焦点处于焦点时div
按下)与将其类更改为的相同操作. 条件渲染首先被触发,因此在应用淡出类之前完全消失。Enter
div
div_out
div
div_out
如何在 divdiv
被关闭时添加淡出功能时保留 div 的条件渲染逻辑?
更新:我发现了使用OnAnimationEnd
的可能性,我认为这将是最容易实现的,而无需彻底检查我的代码。但是,我不确定如何将教程的功能组件代码转换为我项目的类组件代码。
我还发现了使用ReactCSSTransitionGroup
. 链接的教程使用了一个 React 类组件,我正在慢慢尝试对其进行修改并将其转录为下面的代码。但是,我担心ReactCSSTransitionGroup
在我的实际项目中实施(这里没有看到)需要进行相当大的检修,所以我宁愿得到类似OnAnimationEnd
工作的东西。
class MyForm extends React.Component {
constructor(props) {
super(props);
this.myRef = React.createRef();
this.state = { div_enable: false };
}
submitForm = (event) => {
event.preventDefault();
this.setState({ div_enable: true }, () => this.myRef.current.focus());
};
closeModal = () => {
if (event.key === "Enter" && event.shiftKey === false) {
this.setState({ div_enable: false });
}
};
render() {
const { div_enable } = this.state;
return (
<div content>
<form onSubmit={this.submitForm}>
<input
id="text_entry"
type="text"
placeholder="Enter text"
/>
<input type="submit" />
</form>
{div_enable && (
<div
className={div_enable?"div_in":"div_out"}
onKeyDown={this.closeModal}
tabIndex={0}
ref={this.myRef}
>
<p>Press Enter to make me disappear.{" "}
</p>
</div>
)}
</div>
);
}
}
ReactDOM.render(<MyForm />, document.getElementById("root"));
@mixin fade-in {
opacity: 1;
animation-name: fadeInOpacity;
animation-iteration-count: 1;
animation-timing-function: ease-in;
animation-duration: 0.2s;
}
@mixin fade-out {
opacity: 0;
animation-name: fadeInOpacity;
animation-iteration-count: 1;
animation-timing-function: ease-in;
animation-duration: 0.2s;
}
@keyframes fadeInOpacity {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
.div_in {
@include fade-in;
border: 1px solid;
background: lightblue;
}
.div_out {
@include fade-out;
border: 1px solid;
background: lightblue;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
<div id="root"></div>
解决方案
如果你想为你的条件渲染元素启用 CSS 退出动画,你可以完全移除 SCSS 并将你的条件渲染声明(例如,{my_condition && ... }
)转换为标签——同时确保在标签中包含道具(哪个道具是继承自的父组件,)——就像这样:<
CSSTransition
>
unmountOnExit
CSSTransition
Transition
旧:
// Javascript
{div_enable &&
<div className={div_enable?"div_in":"div_out"}>
<p>My paragraph</p>
</div>
}
// CSS
/* [See original question] */
新的:
// Javascript
{
<CSSTransition
in={div_enable}
timeout={200}
classNames="fade"
unmountOnExit
>
<div className="div_in">
<p>My paragraph</p>
</div>
</CSSTransition>
}
// CSS
.div_in {
border: 1px solid;
background: lightblue;
}
.fade-enter {
opacity: 0;
}
.fade-enter-active {
opacity: 1;
transition: opacity 200ms;
}
.fade-exit {
opacity: 1;
}
.fade-exit-active {
opacity: 0;
transition: opacity 200ms;
}
完整代码(我无法在 StackOverflow 的编辑器中导入 ES6 模块({CSSTransition}
) ,因此下面的 StackOverflow 代码无法运行):
import {CSSTransition} from "https://cdnjs.cloudflare.com/ajax/libs/react-transition-group/4.4.1/react-transition-group.min.js";
class MyForm extends React.Component {
constructor(props) {
super(props);
this.myRef = React.createRef();
this.state = {
text_exists_enable: false,
text_empty_enable: false,
text_field: "",
};
}
textEntered = (event) => {
this.setState({ text_field: event.target.value });
console.log(event.target.value);
};
submitForm = (event) => {
event.preventDefault();
if (this.state.text_field !== "") {
this.setState(
{
text_exists_enable: true,
},
() => this.myRef.current.focus()
);
} else {
this.setState(
{
text_empty_enable: true,
},
() => this.myRef.current.focus()
);
}
};
closeBlueBox = () => {
if (event.key === "Enter" && event.shiftKey === false) {
this.setState({
text_exists_enable: false,
text_empty_enable: false,
});
}
};
render() {
const { text_exists_enable, text_empty_enable } = this.state;
return (
<div content>
<form onSubmit={this.submitForm}>
<input
type="text"
placeholder="Enter text"
onChange={this.textEntered}
/>
<input type="submit" />
</form>
{
<CSSTransition
in={text_exists_enable}
timeout={200}
classNames="fade"
unmountOnExit
>
<div
className="div_in"
onKeyDown={this.closeBlueBox}
tabIndex={0}
ref={this.myRef}
>
<p> Textbox HAS text! </p>
</div>
</CSSTransition>
}
{
<CSSTransition
in={text_empty_enable}
timeout={200}
classNames="fade"
unmountOnExit
>
<div
className="div_in"
onKeyDown={this.closeBlueBox}
tabIndex={0}
ref={this.myRef}
>
<p> Textbox is EMPTY! </p>
</div>
</CSSTransition>
}
</div>
);
}
}
ReactDOM.render(<MyForm />, document.getElementById("root"));
.div_in {
border: 1px solid;
background: lightblue;
}
.fade-enter {
opacity: 0;
}
.fade-enter-active {
opacity: 1;
transition: opacity 200ms;
}
.fade-exit {
opacity: 1;
}
.fade-exit-active {
opacity: 0;
transition: opacity 200ms;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-transition-group/4.4.1/react-transition-group.min.js"></script>
<div id="root"></div>
推荐阅读
- java - 如何使用java从PDF文件中读取两个单词之间的多行内容?
- sql - 按关联存在排序记录
- angular - 可以从单元测试中看到方法内部定义的变量
- java - 执行任务时如何将变量写入gradle属性文件?
- awk - 在 AWK 中使用另一个文件查询一个文件的内容
- animation - 使用带有两个嵌套循环的 LaTeX animate & Tikz
- content-management-system - 如何在 sanity io 用户界面中更改字段样式?
- jquery - 删除vue js中表单字段的错误边框
- mysql - 如何在mysql中的一个查询中转换多个更新查询
- java - Java Regex:查找插入、删除、替换计数