はじめに
ようやくReactを触り始めました
ネットからのコピペで適当に作って「React余裕〜うぇ〜〜〜い」って思っていたら
コレ(デモ1)
を
こうしたい(デモ2)
画面遷移にほんのちょっとしたアニメーションをつけようとしただけで、えらく時間がかかってしまいました
環境(package.json抜粋)
"dependencies": {
"react": "^16.6.3",
"react-redux": "^6.0.0",
"react-router": "^4.3.1",
"react-scripts-ts": "3.1.0",
"redux": "^4.0.1",
"typescript-fsa": "^3.0.0-beta-2",
},
"devDependencies": {
"typescript": "^3.2.2"
}
ポイント
- locationにアクセスするために、PropsをRouteComponentPropsを継承したものにする
- CSSTransition にkeyをつけて、locationを一意にハンドリング(これをしないと、アニメーションがつかない)
- Switch にlocationをそのままリレー(これをしないと、アニメーション起動の瞬間で古い画面が遷移先画面になる)
MainComponent.tsx
class MainComponent extends React.Component<IMainProps> {
public render() {
return (
<TransitionGroup>
<CSSTransition key={this.props.location.key} classNames={"pageTransition"} timeout={200} >
<div className={"page"}>
<Switch location={this.props.location}>
<Route exact={true} path='/' component={HomeComponent} />
<Route path='/home' component={HomeComponent} />
<Route path='/page1' component={Page1Component} />
<Route path='/page2' component={Page2Component} />
</Switch>
</div>
</CSSTransition>
</TransitionGroup>
);
}
}
interface IMainProps extends RouteComponentProps<{}>{
}
function mapDispatchToProps(dispatch: Dispatch<any>) {return {};}
function mapStateToProps(appState: any) {return {};}
export default withRouter(connect(mapStateToProps, mapDispatchToProps)(MainComponent));
補足
あとは、CSSTransitionの使い方にならって、適宜アニメーションのCSSを記載
App.css
.page {
position: absolute;
background-color: #fff ;
width:100%;
}
.pageTransition-enter {
opacity: 0;
transform: translateX(100%);
}
.pageTransition-enter-active {
z-index: 2;
transition: opacity 100ms ease-out, transform 200ms ease-out;
opacity: 1;
transform: translateX(0px);
}
.pageTransition-exit-active {
z-index: 1;
}