如何为页面转换正确实施 React Transition Group
How to properly implement React Transition Group for Page Transitions
为了让它发挥作用,我整天都在绞尽脑汁。我注意到的是,无论出于何种原因,转换 classes (classNames="fade") 永远不会应用于页面元素。因此,当我从一个页面导航到另一个页面时,会在短时间内(超时时间)显示两个页面组件。
我应该有600毫秒...
<div class="RTG">
<div class="page fade-appear fade-enter fade-enter-active"> <!--
destination component HTML --></div>
<div class="page fade-exit fade-exit-active"> <!-- start component HTML --></div>
</div>
我得到的是..
<div class="RTG">
<!-- "fade..." classes never applied to the child nodes" -->
<div class="page"> <!-- destination component HTML --></div>
<div class="page"> <!-- start component HTML --></div>
</div>
然后在 600 毫秒超时后,我剩下...
<div class="RTG">
<div class="page"> <!-- destination component HTML --></div>
</div>
注意 1:我将 "RTG" className 放在 TransitionGroup 组件上只是为了验证我的 "page" class 组件实际上是 TransitionGroup 组件的直接后代。由于任何其他原因不存在。
注意 2:我正在使用 react-transition-group@2.4.0,因为我与最新版本存在兼容性问题。
AppRouter.js
import PrivateRoute from './PrivateRoute';
import PublicRoute from './PublicRoute';
import { CSSTransition, TransitionGroup } from 'react-transition-group'
const AppRouter = () => (
<Router history={history}>
<Route render={({location}) => {
return (
<TransitionGroup className="RTG">
<CSSTransition
key={location.key}
timeout={600}
classNames="fade"
>
<Switch location={location}>
<PublicRoute path="/" component={LoginPage} exact={true} />
<PrivateRoute path="/dashboard" component={ExpenseDashboardPage} />
<PrivateRoute path="/create" component={AddExpensePage} />
<PrivateRoute path="/edit/:id" component={EditExpensePage} />
<Route component={NotFoundPage} />
</Switch>
</CSSTransition>
</TransitionGroup>
);
}} />
</Router>
);
export default AppRouter;
PrivateRoute.js
export const PrivateRoute = ({
isAuthenticated,
component: Component,
...rest
}) => (
<Route {...rest} component={(props) => (
isAuthenticated ? (
<div className="page">
<Header />
<Component {...props} />
</div>
) : (
<Redirect to="/" />
)
)} />
);
const mapStateToProps = (state) => ({
isAuthenticated: !!state.auth.uid
});
export default connect(mapStateToProps)(PrivateRoute);
PublicRoute.js
export const PublicRoute = ({
isAuthenticated,
component: Component,
...rest
}) => (
<Route {...rest} component={(props) => (
isAuthenticated ? (
<Redirect to="/dashboard" />
) : (
<div class="page">
<Component {...props} />
</div>
)
)} />
);
const mapStateToProps = (state) => ({
isAuthenticated: !!state.auth.uid
});
export default connect(mapStateToProps)(PublicRoute);
适用CSS 样式
.page {
position: absolute;
top: 0;
left: 0;
right: 0;
}
.fade-appear,
.fade-enter {
opacity: 0;
z-index: 1;
}
.fade-appear-active,
.fade-enter.fade-enter-active {
opacity: 1.0;
transition: opacity 300ms linear 150ms;
}
.fade-exit {
opacity: 1.0;
}
.fade-exit.fade-exit-active {
opacity: 0;
transition: opacity 150ms linear;
}
显然您需要将 <Switch>
包裹在父组件中。
CSSTransition
起作用,因为它会尝试将 classNames
作为道具注入其子项。这意味着子元素将需要使用这些属性并作为 classNames
传递。因此,您需要将 <Switch>
包装到另一个组件中以确保此机制正常工作。
const AppRouter = () => (
<Router>
<Route
render={({ location }) => {
return (
<TransitionGroup className="RTG">
<CSSTransition key={location.key} timeout={600} classNames="fade">
<div>
<Switch location={location}>
<PublicRoute path="/" component={LoginPage} exact={true} />
<PrivateRoute
path="/dashboard"
component={ExpenseDashboardPage}
/>
<PrivateRoute path="/create" component={AddExpensePage} />
<PrivateRoute path="/edit/:id" component={EditExpensePage} />
<Route component={NotFoundPage} />
</Switch>
</div>
</CSSTransition>
</TransitionGroup>
);
}}
/>
</Router>
);
制作流畅漂亮的整页过渡可能很棘手。
大多数解决方案在 route
组件上实现它。
Link方法
在自定义 Link 组件上定义动画。用户导航时,进入下一页,离开当前页面。
<Link
to="/some-path"
transition="glide-right"
/>
当然,为此您必须创建自己的 link...
因此您可以使用执行此操作的软件包,例如 react-tiger-transition。
演示
(我是作者)
为了让它发挥作用,我整天都在绞尽脑汁。我注意到的是,无论出于何种原因,转换 classes (classNames="fade") 永远不会应用于页面元素。因此,当我从一个页面导航到另一个页面时,会在短时间内(超时时间)显示两个页面组件。
我应该有600毫秒...
<div class="RTG">
<div class="page fade-appear fade-enter fade-enter-active"> <!--
destination component HTML --></div>
<div class="page fade-exit fade-exit-active"> <!-- start component HTML --></div>
</div>
我得到的是..
<div class="RTG">
<!-- "fade..." classes never applied to the child nodes" -->
<div class="page"> <!-- destination component HTML --></div>
<div class="page"> <!-- start component HTML --></div>
</div>
然后在 600 毫秒超时后,我剩下...
<div class="RTG">
<div class="page"> <!-- destination component HTML --></div>
</div>
注意 1:我将 "RTG" className 放在 TransitionGroup 组件上只是为了验证我的 "page" class 组件实际上是 TransitionGroup 组件的直接后代。由于任何其他原因不存在。
注意 2:我正在使用 react-transition-group@2.4.0,因为我与最新版本存在兼容性问题。
AppRouter.js
import PrivateRoute from './PrivateRoute';
import PublicRoute from './PublicRoute';
import { CSSTransition, TransitionGroup } from 'react-transition-group'
const AppRouter = () => (
<Router history={history}>
<Route render={({location}) => {
return (
<TransitionGroup className="RTG">
<CSSTransition
key={location.key}
timeout={600}
classNames="fade"
>
<Switch location={location}>
<PublicRoute path="/" component={LoginPage} exact={true} />
<PrivateRoute path="/dashboard" component={ExpenseDashboardPage} />
<PrivateRoute path="/create" component={AddExpensePage} />
<PrivateRoute path="/edit/:id" component={EditExpensePage} />
<Route component={NotFoundPage} />
</Switch>
</CSSTransition>
</TransitionGroup>
);
}} />
</Router>
);
export default AppRouter;
PrivateRoute.js
export const PrivateRoute = ({
isAuthenticated,
component: Component,
...rest
}) => (
<Route {...rest} component={(props) => (
isAuthenticated ? (
<div className="page">
<Header />
<Component {...props} />
</div>
) : (
<Redirect to="/" />
)
)} />
);
const mapStateToProps = (state) => ({
isAuthenticated: !!state.auth.uid
});
export default connect(mapStateToProps)(PrivateRoute);
PublicRoute.js
export const PublicRoute = ({
isAuthenticated,
component: Component,
...rest
}) => (
<Route {...rest} component={(props) => (
isAuthenticated ? (
<Redirect to="/dashboard" />
) : (
<div class="page">
<Component {...props} />
</div>
)
)} />
);
const mapStateToProps = (state) => ({
isAuthenticated: !!state.auth.uid
});
export default connect(mapStateToProps)(PublicRoute);
适用CSS 样式
.page {
position: absolute;
top: 0;
left: 0;
right: 0;
}
.fade-appear,
.fade-enter {
opacity: 0;
z-index: 1;
}
.fade-appear-active,
.fade-enter.fade-enter-active {
opacity: 1.0;
transition: opacity 300ms linear 150ms;
}
.fade-exit {
opacity: 1.0;
}
.fade-exit.fade-exit-active {
opacity: 0;
transition: opacity 150ms linear;
}
显然您需要将 <Switch>
包裹在父组件中。
CSSTransition
起作用,因为它会尝试将 classNames
作为道具注入其子项。这意味着子元素将需要使用这些属性并作为 classNames
传递。因此,您需要将 <Switch>
包装到另一个组件中以确保此机制正常工作。
const AppRouter = () => (
<Router>
<Route
render={({ location }) => {
return (
<TransitionGroup className="RTG">
<CSSTransition key={location.key} timeout={600} classNames="fade">
<div>
<Switch location={location}>
<PublicRoute path="/" component={LoginPage} exact={true} />
<PrivateRoute
path="/dashboard"
component={ExpenseDashboardPage}
/>
<PrivateRoute path="/create" component={AddExpensePage} />
<PrivateRoute path="/edit/:id" component={EditExpensePage} />
<Route component={NotFoundPage} />
</Switch>
</div>
</CSSTransition>
</TransitionGroup>
);
}}
/>
</Router>
);
制作流畅漂亮的整页过渡可能很棘手。
大多数解决方案在 route
组件上实现它。
Link方法
在自定义 Link 组件上定义动画。用户导航时,进入下一页,离开当前页面。
<Link
to="/some-path"
transition="glide-right"
/>
当然,为此您必须创建自己的 link...
因此您可以使用执行此操作的软件包,例如 react-tiger-transition。
演示
(我是作者)