React@16.x(35)动画(下)封装动画组件需要注意的问题

接上篇文章 React动画(中)

1,封装举例

封装一个渐入渐出效果的动画组件

import { CSSTransition } from "react-transition-group";
import "./FadeTransition.css";

export default function FadeTransition(props) {
    return <CSSTransition {...props}>{props.children}</CSSTransition>;
}
/* FadeTransition.css */
.appear {
    opacity: 0;
}

.appear-active {
    opacity: 1;
    transition: opacity 1s;
}

.enter {
    opacity: 0;
}
.enter-active {
    opacity: 1;
    transition: opacity 1s;
}

.exit-active {
    opacity: 0;
    transition: opacity 1s;
}

.exit-done {
    opacity: 0;
}

使用

import { useState } from "react";
import FadeTransition from "./FadeTransition";

export default function App() {
    const [state, setState] = useState(true);
    return (
        <>
            <button onClick={() => setState(!state)}>{state ? "隐藏" : "显示"}</button>
            <FadeTransition in={state} appear timeout={1000}>
                <h1>标题1</h1>
            </FadeTransition>
        </>
    );
}

2,问题

2.1,timeout

可以看到,传递的 timeout 需要和 css 中的过渡时间保持一致。

解决:将 css 文件中设置的 transition 属性都移除掉,通过内联样式设置。

内联样式通过钩子函数来设置:

import { CSSTransition } from "react-transition-group";
import "./FadeTransition.css";

FadeTransition.defaultProps = {
    timeout: 500,
};

const addTransition = (node, timeout) => {
    node.style.transition = `opacity ${timeout}ms`;
};

const removeTransition = (node) => {
    node.style.transition = "";
};

export default function FadeTransition(props) {
    return (
        <CSSTransition
            {...props}
            onEnter={(node) => addTransition(node, props.timeout)}
            onEntered={(node) => removeTransition(node)}
            onExit={(node) => addTransition(node, props.timeout)}
            onExited={(node) => removeTransition(node)}
        >
            {props.children}
        </CSSTransition>
    );
}

2.2,配合 SwitchTransition / TransitionGroup

SwitchTransition 组件会调用 CSSTransition 组件的 onExited 方法,让下个元素执行进入动画,所以需要执行传入的 props.onExited(node)

其实,这几个动画组件在不同的动画状态,添加对应的类名,都是在这些钩子函数中实现的。

export default function FadeTransition(props) {
    return (
        <CSSTransition
            {...props}
            onEnter={(node) => addTransition(node, props.timeout)}
            onEntered={(node) => removeTransition(node)}
            onExit={(node) => addTransition(node, props.timeout)}
            onExited={(node) => {
                removeTransition(node);
                props.onExited && props.onExited(node);
            }}
        >
            {props.children}
        </CSSTransition>
    );
}

使用:

export default function App() {
    const [state, setState] = useState(true);
    return (
        <>
            <button onClick={() => setState(!state)}>切换</button>
            <SwitchTransition>
                <FadeTransition key={state} appear timeout={1000}>
                    <h1>{state ? "标题1" : "标题2"}</h1>
                </FadeTransition>
            </SwitchTransition>
        </>
    );
}

TransitionGroup 同理,不再赘述。


以上。

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

下雪天的夏风

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值