由vue过渡到react,在react中想给页面或组件添加类似于vue里面的transition,并附带out-in的模式的时候(即当前元素先进行过渡,完成之后新元素过渡进入),发现以下几个问题并逐一解决:
使用版本
项目使用create-react-app创建
{
react:"16.9.1",
react-router-dom:"^5.0.1",
react-transition-group: "^4.3.0"
}
Q1:如何实现React按需加载?
参考官方文档:react-1251415695.cos-website.ap-chengdu.myqcloud.com/docs/code-s…
const message = lazy(() => import('./Message/messageCenter'))
const analysis = lazy(() => import('./DataAnalysis/dataAnalysis'))
function MyComponent() {
return (
<div>
<Suspense fallback={<div>Loading...</div>}>
<OtherComponent />
</Suspense>
</div>
);
}
React.lazy 和 Suspense 技术还不支持服务端渲染。
Q2:如何实现页面过渡效果?
网上的教程大多数为老版本,现在官方提供的是叫react-transition-group,但是官网写得不怎么友好,阅读起来有点困难
主要分为以下四个部分:
- Transition:给单个组件添加过渡
- CSSTransition:控制过渡动画效果的模块,需要配合使用
- SwitchTransition(新增):参考vue的out-in的模式实现的,控制组件进入和离开动画的加载顺序,避免只能同时加载
- TransitionGroup:给列表组件添加过渡
具体使用及配合React-Router使用
参考进行使用:segmentfault.com/a/119000001… ,此处不再赘述
看完上述文章实现vue-router过渡,再配合上按需加载,你就会得到:
import React, {Component, Suspense, lazy } from 'react';
import { Route,Switch,RouteComponentProps } from "react-router-dom";
import './allStyle.css'
import { CSSTransition, TransitionGroup } from 'react-transition-group';
const message = lazy(() => import('./Message/messageCenter'))
const analysis = lazy(() => import('./DataAnalysis/dataAnalysis'))
class AppRouter extends Component<RouteComponentProps>{
render(){
const {history,location} = this.props
return(
<Suspense fallback={<div>Loading...</div>}>
<TransitionGroup>
<CSSTransition
classNames={'fade'}
key={location.pathname}
timeout={300}>
<Switch location={location}>
<Route path="/messagecenter" component={message} />
<Route path="/analysis" component={analysis} />
<Route component={defaultError} />
</Switch>
</CSSTransition>
</TransitionGroup>
</Suspense>
)
}
}
export default AppRouter;
注意: 1. 记得留意上述组件的层次顺序,不能出错,Suspense->TransitionGroup->CSSTransition->Switch。 2. switch 的location记得获取到路由的location
Q3:按需加载和过渡一起使用产生了哪些问题?
1.react-router官网推荐使用的按需加载实现是loadable,测试后发现会出现白屏、无法跳转的情况,所以此处决定修改按需加载方案为React.lazy。
2.将按需加载的实现改为react自带的React.lazy来实现后,已经很接近了,按需加载和过渡都能同时实现(参考Q2代码)

细心的你可能已经发现了,如果没有类似于vue的out-in这样的动画模式控制的话,过渡动画是只能同时执行,然后需要移除的组件和需要加载的组件就会同时出现,右侧就会产生滚动条,很影响用户体验。
这时候我们的SwitchTransition就可以派上用场了
// 省略部分代码...
import { CSSTransition, TransitionGroup, SwitchTransition } from 'react-transition-group';
class AppRouter extends Component{
render(){
return(
<Suspense fallback={<div>Loading...</div>}>
<TransitionGroup>
<SwitchTransition>
<CSSTransition
classNames={'fade'}
key={location.pathname}
timeout={300}>
<Switch location={location}>
<Route path="/messagecenter" component={message} />
<Route path="/analysis" component={analysis} />
<Route component={defaultError} />
</Switch>
</CSSTransition>
</SwitchTransition>
</TransitionGroup>
</Suspense>
)
}
}
export default AppRouter;

问题解决啦!SwitchTransition整体实现思路都是参照vue的,默认为out-in模式,如果有其他设置参数的需求,参照官网就可以啦。
如有错误,请指正一下啦谢谢。