处理'覆盖页面'使用React路由器?

时间:2018-05-30 12:51:02

标签: reactjs react-router react-router-v4

我正在努力实现一种能够实现“覆盖”的路由风格。 pages - 显示在上一页顶部的模态窗口(仍然可见,因为叠加层是半透明的),但确实更改了URL。这种风格的一个很好的例子是Product Hunt' homepage

我之前通过在Switch之外渲染覆盖的Route,然后将路径与链接源匹配(它可以预测地仅从两个不同的视图链接)来找到解决方案。这很好用。

看起来像这样:

    <Switch>
      <Route exact path="/" component={Home} />
      <Route exact path="/search" component={Search} />
      <Route exact path="/:category" component={Category} />
      <Route exact path="/:category/:id" component={Category} /> // this matches when overlay is active
    </Switch>
    <Route exact path="/:category/:id" component={Overlay} />

现在,可以从搜索页面显示叠加层,点击搜索结果将更改基础视图,理想情况下,如果用户关闭叠加层或使用后退按钮,它将保持不变。

这使我重新考虑我的实施。我没有直接使用<Link>来管理叠加层的显示,而是使用React Context来控制叠加层,现在可以在挂载时更改网址。目前这会产生与以前相同的行为,但我想知道我能做些什么来保存&#39;上一个网址,然后用它来控制<Switch>组件呈现的内容?

如果有人对此类行为有任何意见或经验,我们表示赞赏。如果我找到一个好的解决方案,我会确保回复我的解决方案。

2 个答案:

答案 0 :(得分:2)

在对react-router文档进行了一些研究之后,我发现可以控制Switch组件的withRouter道具,这正是我所需要的。所以我创建了一个使用Switch HOC来分析位置变化的包装器组件,如果当前位置路径与我的重叠路径匹配,则会向location提供“先前”位置对象,否则它提供当前的。因为Switch道具不会根据this.data而改变,所以基础视图不会改变或重新渲染,从而给出了我所追求的确切行为。

答案 1 :(得分:0)

以@sherlock答案为基础,我的解决方案在TypeScript中看起来像这样。

class FeedItemsPage extends React.Component<AllProps> {
  private location: Location

  constructor(props: AllProps) {
    super(props)

    this.location = props.location
    this.overrideLocation()
  }

  componentDidUpdate(prevProps: AllProps) {
    if (this.props.location !== prevProps.location) {
      this.overrideLocation()
    }
  }

  public render() {
    const { match } = this.props

    return (
      <>
        <Switch location={this.location}>
          <Route exact path={match.path + '/'} component={FeedItemsIndexPage} />
        </Switch>
        <Route path={match.path + '/:id'} component={FeedItemPage} />
      </>
    )
  }

  overrideLocation() {
    let location = Object.assign({}, this.props.location)
    location.pathname = this.props.match.path
    this.location = location
  }
}