如何在React-Router 4 <switch> <redirect>中保存查询字符串和哈希片段?

时间:2018-08-16 03:10:43

标签: reactjs react-router-v4

如果您在<Redirect>内有<Route>,则将获得location并可以执行:<Redirect search={props.location.search} hash={props.location.hash} ...

但是,当直接位于顶层<Switch>内时,<Redirect>没有任何props.location可以访问searchhash

在顶级<Redirect>之后(在树的上方没有<Switch>之后)的<Route>中是否没有办法保留查询字符串和哈希片段?

示例:(打字稿)

Router({},
  Switch({},
    Redirect({ path: '/', to: '/latest', exact: true }))))

to: '/latest'更改为to: { pathname:... search:.. hash:.. }无效,因为没有props.location可访问原始的.search.hash

此处(https://github.com/ReactTraining/react-router/issues/5818#issuecomment-384934176)开发人员说,保留查询和哈希的问题已解决,但在上述情况下我找不到任何有效的方法:

  

>是否可以选择在重定向时保存查询字符串?

     

>它将在4.3.0中实现。请在此处查看发行说明:https://github.com/ReactTraining/react-router/releases/tag/v4.3.0-rc.1

这些发行说明链接到:https://github.com/ReactTraining/react-router/pull/5209,其中没有提到任何可行的方法。

也许它们只意味着<Redirect>内的<Route>?然后,可以执行以下操作:

Route({ path: ..., render: (props) => function() {
  Redirect({ to: { pathname:... search: props.location.search, ... } ...}));

4 个答案:

答案 0 :(得分:1)

<Redirect />组件拥有自己的历史记录订阅者之前,您可以创建自己的历史记录:

const RouteAwareRedirect = props => (
  <Route render={routeProps => 
    <Redirect to={props.to(routeProps)} />
  }/>
)

然后在任何需要的地方使用它:

<RouteAwareRedirect to={({ location }) => ({ 
  // use location.pathname, etc .. 
}) />

答案 1 :(得分:0)

如果没有其他方法(显然没有办法,请参阅Azium的答案)...然后这有效:-)至少使用exactstricttrue没有测试其他连击。

使用方法如下:(而且它只会更改路径,而不是查询字符串或哈希)

RedirPath({ path: '/', to: '/latest', exact: true })

,并且可以在<Switch>中使用,而上面没有<Route>。里面有一个<Route>:-P您需要删除dieIf

许可证:麻省理工学院。 (不是CC0。)

/**
 * Redirects the URL path only — preserves query string and hash fragment.
 */
export function RedirPath(props: { path: string, to: string, exact: boolean, strict?: boolean }) {
  // @ifdef DEBUG
  dieIf(props.to.indexOf('?') >= 0, 'TyE2ABKS0');
  dieIf(props.to.indexOf('#') >= 0, 'TyE5BKRP2');
  // @endif
  const path = props.path;
  const exact = props.exact;
  const strict = props.strict;
  return Route({ path, exact, strict, render: (routeProps) => {
    return Redirect({
      from: path, exact, strict,
      to: {
        pathname: props.to,
        search: routeProps.location.search,
        hash: routeProps.location.hash }});
  }});
}

答案 2 :(得分:0)

您可以像这样扩展<Redirect />

const UtmFriendlyRedirect = props => (
    <Redirect computedMatch={props.computedMatch}
              to={{pathname: props.to, search: props.location.search}}/>
)

然后以与普通重定向相同的方式使用它:

<UtmFriendlyRedirect from='/:articleId' to='/article/:articleId'/>

答案 3 :(得分:0)

在我非常有限的测试中,这会保留所有搜索参数。

const RedirectAndPreserveSearch = ({ to, ...additionalProps }) => (
  <Redirect
    {...additionalProps}
    to={{
      pathname: to,
      search: new URL(window.location.href).search,
    }}
  />
);

我认为这仅在没有其他因素干扰搜索参数的情况下才有效(我不确定这是否会更新该组件吗?它可能会在安装时随搜索参数一起重定向?)

我还没有尝试过,但是您也可以对哈希进行类似的操作。