【发布时间】:2019-01-20 21:01:13
【问题描述】:
这是一个关于 React 路由器及其设计的问题,特别是在考虑页面转换时。
React 是为模块化而设计的,它在该领域表现出色。但我发现在保持组件之间的隔离和模块化的同时,似乎很难完成一项任务:页面转换。
我确实阅读了很多与此相关的文章和问题,包括 Medium 和 StackOverFlow 以及其他网站;但到目前为止,我还没有阅读任何关于解决我将在这里解决的问题的良好架构方法的描述,以及关于为什么 React 路由器不考虑这种常见情况的解释。
让我们考虑一个包含三个页面的网站,PageA、PageB 和 PageC:
如果我们想使用相同的动画来挂载/卸载这三个页面,假设一个 FadeIn 用于挂载,一个 FadeOut 用于卸载,那么我们可以使用React Transition Group 组件来包装我们的<Switch> 组件,它将负责使用 CSS 转换为页面设置动画。这里的 CSS 过渡将由 <CSSTransition> 组件控制,类传递给 ClassNames。
<div className="Main">
<TransitionGroup component={null}>
<CSSTransition
key={locationKey}
appear={true}
classNames="Main"
timeout={{
enter: 300,
exit: 300,
}}
>
<Switch location={this.props.location}>
<Route
path="/PageA"
render={(props) => {
return <PageA />;
}}
/>
<Route
path="/PageB"
render={(props) => {
return <PageA />;
}}
/>
<Route
path="/PageC"
render={(props) => {
return <PageA />;
}}
/>
</Switch>
</CSSTransition>
</TransitionGroup>
</div>
一切都好,我们很高兴,我们的网站有一些漂亮的动画,用于安装和卸载。
现在我们要为每个页面的每个安装/卸载操作进行不同的转换:PageA 使用 FadeIn 安装并使用 FadeOut 卸载,PageB 使用从左到右的滑动安装和卸载滑动回到左边,PageC 从下往上挂载,从下往下滑卸载。
我们将面临两个问题:如果我们使用<CSSTransition> 组件,我们将不得不根据渲染的页面向它传递不同的classNames 属性。我还没有用这个策略实现任何东西,因为还有一个问题让我担心:如果按照这个路径,我们会将用于动画页面组件的逻辑存储在<CSSTransition>组件中,而这是在页面之外。这在我看来并不是非常模块化和孤立的,而且我阅读的关于软件设计、模块化和孤立的书籍越多,我就越对这种方法感到困惑。
在理想情况下,页面动画的逻辑应该在每个页面的主要组件中定义。比如:
class Home extends React.Component {
constructor(props) {
super(props);
this.state = {
classForAnimation: '',
};
}
componentDidMount() {
this.setState({
classForAnimation: ' FadeIn',
});
}
render() {
return <div className={'Home' + this.state.classForAnimation}>
I'm Home page
</div>;
}
}
export default Home;
还有一些 CSS:
.Home {
opacity: 0;
transition: opacity 0.5s ease;
}
.FadeIn {
opacity: 1;
}
这只是为了安装,真的很容易。所以,如果这是一个更好的解决方案,¿为什么我们不使用它?
原因是因为 React-router 不知道我们的转换,它会立即卸载页面以进行动画处理,甚至无需等待动画开始——当然,完成——强>。这就是<CSSTransition> 组件所做的,但将页面转换的逻辑集中在页面组件之外。
因此,考虑到多个页面在装载/卸载时具有不同动画的情况,这是我的问题:
A) 之间的转换逻辑是否有任何原因? 页面不应该存储在每个页面的主要组件中吗?
B) React-router 被设计为卸载有什么原因吗 组件忽略等待不同类型事件的情况 在不同的页面?
C) 有没有我没有考虑的通用方法来解决这个问题?
D) 从头开始编写自定义 React 路由器是一种选择吗?
尼克。
【问题讨论】:
标签: reactjs react-router reactcsstransitiongroup