问题
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