How preserve query string and hash fragment, in React-Router 4 <Switch><Redirect>?

前提是你 提交于 2020-01-02 09:55:37

问题


If you have a <Redirect> inside a <Route>, you'll get a location and can do: <Redirect search={props.location.search} hash={props.location.hash} ....

However, when directly inside a top level <Switch>, the <Redirect> doesn't have any props.location to access search and hash on.

Is there no way to preserve the query string and hash fragment, in a <Redirect> directly after a top level <Switch> (no <Route> higher up in the tree)?

Example: (Typescript)

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

Changing to: '/latest' to to: { pathname:... search:.. hash:.. } doesn't work because there's no props.location available to access the original .search and .hash on.

Here (https://github.com/ReactTraining/react-router/issues/5818#issuecomment-384934176 ) the devs says the preserve-query-and-hash problem has been solved but I cannot find anything that works in the above case:

> any option the save query string on redirect?

> it will be implemented in 4.3.0. See release notes here: https://github.com/ReactTraining/react-router/releases/tag/v4.3.0-rc.1

Those release notes links to: https://github.com/ReactTraining/react-router/pull/5209 which doesn't mention anything that seems to work.

Maybe they meant only for <Redirect> inside a <Route> already? Then, one can do something like:

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

回答1:


Until the <Redirect /> component gets its own history subscriber, you can make your own:

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

Then use that where ever you want:

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



回答2:


If there's no other way (apparently there isn't, see Azium's answer) ... then this works :- ) at least with exact and strict both true (haven't tested other combos).

Use like so: (and it'll change the path only, not query string or hash)

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

and works in a <Switch> with no <Route> above. There's a <Route> inside instead :- P You need to remove dieIf.

License: MIT. (Not 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 }});
  }});
}


来源:https://stackoverflow.com/questions/51869083/how-preserve-query-string-and-hash-fragment-in-react-router-4-switchredirect

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!