-
-
Notifications
You must be signed in to change notification settings - Fork 5.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Doc] Explain how to change page with useNavigation
#9840
Changes from 3 commits
89998ed
96a3ac3
6550683
13d4dff
70e5c8d
664705a
c9bdf81
58ee000
7e76df2
f61e510
fc6013a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
import * as React from 'react'; | ||
import { Link, Routes, Route, useLocation } from 'react-router-dom'; | ||
|
||
import { FakeBrowserDecorator } from '../storybook//FakeBrowser'; | ||
import { useRedirect as useRedirectRA } from './useRedirect'; | ||
|
||
export default { | ||
title: 'ra-core/routing', | ||
decorators: [FakeBrowserDecorator], | ||
}; | ||
|
||
const Home = () => { | ||
const redirect = useRedirectRA(); | ||
return ( | ||
<> | ||
<h1>Home</h1> | ||
<ul> | ||
<li> | ||
<button onClick={() => redirect('/dashboard')}> | ||
Dashboard | ||
</button> | ||
</li> | ||
<li> | ||
<button onClick={() => redirect('list', 'posts')}> | ||
Post list | ||
</button> | ||
</li> | ||
<li> | ||
<button onClick={() => redirect('edit', 'posts', 123)}> | ||
123th post detail | ||
</button> | ||
</li> | ||
<li> | ||
<button | ||
onClick={() => | ||
redirect({ | ||
pathname: '/some/path', | ||
search: '?query=string', | ||
hash: '#hash', | ||
state: null, | ||
key: 'my_key', | ||
}) | ||
} | ||
> | ||
My page | ||
</button> | ||
</li> | ||
<li> | ||
<button | ||
onClick={() => | ||
redirect((resource, id, data) => { | ||
return data?.hasComments ? 'comments' : 'posts'; | ||
}) | ||
} | ||
> | ||
Redirect function | ||
</button> | ||
</li> | ||
</ul> | ||
</> | ||
); | ||
}; | ||
|
||
const Dashboard = () => ( | ||
<div> | ||
<h1>Admin dashboard</h1> | ||
<Link to="/">Home</Link> | ||
</div> | ||
); | ||
|
||
const PostList = () => ( | ||
<div> | ||
<h1>Posts</h1> | ||
<Link to="/">Home</Link> | ||
</div> | ||
); | ||
|
||
const PostDetail = () => ( | ||
<div> | ||
<h1>Post 123</h1> | ||
<Link to="/">Home</Link> | ||
</div> | ||
); | ||
|
||
const SomePage = () => { | ||
const location = useLocation(); | ||
return ( | ||
<div> | ||
<h1>My Page</h1> | ||
<Link to="/">Home</Link> | ||
<hr /> | ||
<p>Location: {location.pathname}</p> | ||
<p>Location: {location.search}</p> | ||
<p>Hash: {location.hash}</p> | ||
</div> | ||
); | ||
}; | ||
|
||
export const useRedirect = () => ( | ||
<Routes> | ||
<Route path="/" element={<Home />} /> | ||
<Route path="/dashboard" element={<Dashboard />} /> | ||
<Route path="/posts" element={<PostList />} /> | ||
<Route path="/posts/123" element={<PostDetail />} /> | ||
<Route path="/some/path" element={<SomePage />} /> | ||
</Routes> | ||
); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
import { useCallback } from 'react'; | ||
import { useNavigate, To } from 'react-router-dom'; | ||
import { Location } from 'history'; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why don't you import the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Because there is any |
||
import { Identifier, RaRecord } from '../types'; | ||
|
||
import { useBasename } from './useBasename'; | ||
|
@@ -12,7 +13,11 @@ type RedirectToFunction = ( | |
state?: object | ||
) => To; | ||
|
||
export type RedirectionSideEffect = CreatePathType | false | RedirectToFunction; | ||
export type RedirectionSideEffect = | ||
| CreatePathType | ||
| false | ||
| RedirectToFunction | ||
| Location; | ||
|
||
/** | ||
* Hook for Redirection Side Effect | ||
|
@@ -30,6 +35,8 @@ export type RedirectionSideEffect = CreatePathType | false | RedirectToFunction; | |
* redirect(false); | ||
* // redirect to the result of a function | ||
* redirect((resource, id, data) => ...) | ||
* // redirect to a Location object | ||
* redirect({ pathname: '/some/path', search: '?query=string', hash: '#hash', state: null, key: 'my_key' }); | ||
*/ | ||
export const useRedirect = () => { | ||
const navigate = useNavigate(); | ||
|
@@ -59,6 +66,9 @@ export const useRedirect = () => { | |
state: { _scrollToTop: true, ...state }, | ||
}); | ||
return; | ||
} else if (typeof redirectTo === 'object') { | ||
navigate(redirectTo); | ||
return; | ||
} else if ( | ||
typeof redirectTo === 'string' && | ||
redirectTo.startsWith('http') && | ||
|
@@ -70,14 +80,21 @@ export const useRedirect = () => { | |
return; | ||
} else { | ||
// redirection to an internal link | ||
navigate(createPath({ resource, id, type: redirectTo }), { | ||
state: | ||
// We force the scrollToTop except when navigating to a list | ||
// where this is already done by <RestoreScrollPosition> in <Resource> | ||
redirectTo === 'list' | ||
? state | ||
: { _scrollToTop: true, ...state }, | ||
}); | ||
navigate( | ||
createPath({ | ||
resource, | ||
id, | ||
type: redirectTo as CreatePathType, | ||
}), | ||
{ | ||
state: | ||
// We force the scrollToTop except when navigating to a list | ||
// where this is already done by <RestoreScrollPosition> in <Resource> | ||
redirectTo === 'list' | ||
? state | ||
: { _scrollToTop: true, ...state }, | ||
} | ||
); | ||
erwanMarmelab marked this conversation as resolved.
Show resolved
Hide resolved
|
||
return; | ||
} | ||
}, | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd use types as labels for your buttons: Relative url, View name, View name with details, Location, Function
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice idea, applied 👍