@watch-state/react-router
This package provides you the browser routing for:
- React v16.8+
watch-state v3+
Install
npmnpm i @watch-state/react-router
yarn
yarn add @watch-state/react-router
The simplest way of using is Create React App.
Router
UseRouter
anywhere to show content by URL matching.```typescript jsx import Router, {history} from '@watch-state/react-router' // or // import Router, {history} from '@watch-state/react-router/Router'
const App = () => (
<button onClick={() => history.push('/')}>home</button> |
<button onClick={() => history.push('/test')}>test</button>
<div>
This is
<Router path='/'>
home
</Router>
<Router path='/test'>
test
</Router>
page
</div>
The `history` is [@watch-state/history-api](https://www.npmjs.com/package/@watch-state/history-api).
### path ![string](https://img.shields.io/badge/-string-green)
Use `path` to show router content by URL path
```typescript jsx
const Test = () => <Router path='/test'>test</Router>
test
will be shown when url equals/test
or/test?key=value#test
but not for/test/420
or/user/test
.
You can use it as regexp.
```typescript jsx const Test = () => test
> `test` will be shown when url path equals `/foo` or `/bar`.
You can get `foo` or `bar` by children function
```typescript jsx
const Test = () => <Router path='/(foo|bar)'>{get => get(1)}</Router>
/foo
returnsfoo
and/bar
returnsbar
.
The number in the
get
function says which brackets you want to use.```typescript jsx const Test = () => {get => get(2)}
> `/foo/13` returns `13` and `/bar/420` returns `420`.
### match ![string](https://img.shields.io/badge/-string-green)
Use `match` if you want to match URL by custom regexp
```typescript jsx
const Test = () => <Router match='^/(foo|bar)'>FOOBAR</Router>
/foo/13
returnsFOOBAR
and/bar
returnsFOOBAR
.
If you use
match
then path
, search
, hash
, ish
, pathIsh
, searchIsh
and hashIsh
are not be used.You can use a function as a child to get the value of the matching like for
path
.pathIsh
UsepathIsh
to make the soft routing by path. That means the path should start with path
property.```typescript jsx const Test = () => FOOBAR
> `/foo/13` returns `FOOBAR` and `/bar/420/test?key=value#test` returns `FOOBAR`.
> Starts with `/foo` or `/bar`.
### ish ![boolean](https://img.shields.io/badge/-boolean-orange)
Use `ish` instead of `pathIsh`, `searchIsh` and `hashIsh` equal `true`
```typescript jsx
const Test = () => <Router path='/(foo|bar)' ish>FOOBAR</Router>
The same as pathIsh
search
Usesearch
if you want to show content by search query of URL.```typescript jsx const Test = () => test
> `/foo/13?key=value#420` returns `test` but `/foo/13?key=value&test` returns empty content.
### searchIsh ![boolean](https://img.shields.io/badge/-boolean-orange)
Use `searchIsh` or `ish` to make a soft search.
```typescript jsx
const Test = () => <Router search='key=value' ish>test</Router>
now/foo/13?key=value&test
and/foo/13?test=1&key=value&foo=bar
returnstest
.
Also, you can use only key for search
```typescript jsx const Test = () => test
> `/?key&value` and `/?value&key` returns `test` but `/?key=1` and `/?key1` returns nothing.
### hash ![string](https://img.shields.io/badge/-string-green)
Use `hash` if you want to show content by hash of URL.
```typescript jsx
const Test = () => <Router hash='test'>test</Router>
/any/path?any=search#test
returnstest
but/#test1
returns empty content.
hashIsh
UsehashIsh
or ish
to fix it.```typescript jsx const Test = () => test
> now `/#test1` and `/#sometextwiththetestword` returns `test`.
### other ![boolean](https://img.shields.io/badge/-boolean-orange)
This is an alternative of react `Switch`.
`Router` with `other` shows content only if all routers without `other` in the same `Router` are not matched.
```typescript jsx
const Test = () => (
<Router>
<Router path='/'>home</Router>
<Router path='/user'>user</Router>
<Router other>other</Router>
</Router>
)
```
> will show `home` for `/`, `user` for `/user` and `other` for any other url
You may use any structure inside `Router` and several `other` routers with any props.
```typescript jsx
const Test = () => (
<Router>
<div>
<Router path='/'>home</Router>
<div>
content
<Router path='/user'>user</Router>
</div>
<Router search='modal' other>modal</Router>
<Router other>
<Router path='/test'>test</Router>
<Router other><div>other</div></Router>
</Router>
</div>
</Router>
)
```
### showDelay ![number](https://img.shields.io/badge/-number-blue)
You can show content of router with delay.
```typescript jsx
const Test = () => <Router path='/test' showDelay={1000}>test</Router>
```
> when URL became `/test` the content be not shown, `test` will be shown in a second after that.
### hideDelay ![number](https://img.shields.io/badge/-number-blue)
This is the same `showDelay` but for hiding.
```typescript jsx
const Test = () => <Router path='/test' hideDelay={1000}>test</Router>
```
> when URL became `/test` the content be shown immediately, but when URL is changed after that, `test` will be hidden in a second.
### delay ![number](https://img.shields.io/badge/-number-blue)
This is the combine of `showDelay` and `hideDelay`.
```typescript jsx
const Test = () => <Router path='/test' delay={1000}>test</Router>
test
will be shown or hidden in a second.
onShow
It calls any time when the content will be shown```typescript jsx const Test = () => (
path='/test'
onShow={() => console.log('test')}>
test
)
### onShown ![function-void](https://img.shields.io/badge/function-void-orange)
It calls any time when the content has shown
```typescript jsx
const Test = () => (
<Router
path='/test'
delay={1000}
onShown={() => console.log('test')}>
test
</Router>
)
onHide
It calls any time when the content will be hidden```typescript jsx const Test = () => (
path='/test'
onHide={() => console.log('test')}>
test
)
### onHidden ![function-void](https://img.shields.io/badge/function-void-orange)
It calls any time when the content has hidden
```typescript jsx
const Test = () => (
<Router
path='/test'
delay={1000}
onHidden={() => console.log('test')}>
test
</Router>
)
Redirect
Use the component for comfortable redirectionimport {Redirect} from '@watch-state/react-router'
url
Use the prop to redirect at the url.```typescript jsx const RedirectToHome = () => ( )
const RedirectToLogin = () => ( )
const RedirectToHeader = () => ( )
const RedirectToRepo = () => ( )
### path ![string](https://img.shields.io/badge/-string-green)
The same as `url` but works only with path.
```typescript jsx
const RedirectToHome = () => (
<Redirect path='/' />
)
You may combine with
url
```typescript jsx const RedirectToHome = () => ( ) // redirects to /#bar
### search ![string](https://img.shields.io/badge/-string-green) ![object](https://img.shields.io/badge/-object-orange)
The same as `path` but works with search and you may combine with `url`
```typescript jsx
const RedirectToLoginModal = () => (
<Redirect search='modal=login' />
)
// redirects to ?modal=login
You may use an object of search keys and values
```typescript jsx const RedirectToLoginModal = () => ( ) // redirects to ?modal=login
`undefined` value removes the key
```typescript jsx
history.push('/test?key=value')
render (
<Redirect search={{key: undefined}} />
)
// redirects to /test
hash
The same aspath
but works with hash and you may combine with url
```typescript jsx const RedirectToRoot = () => ( ) // redirects to #root
### push ![boolean](https://img.shields.io/badge/-boolean-orange)
By default `Redirect` replaces url. If you wanna push the redirection to history use the property.
```typescript jsx
const RedirectToHome = () => (
<Redirect path='/' push />
)
position
By default the page scrolls up during redirection. You may change the scroll position by the property.```typescript jsx const RedirectToHome = () => ( )
You may scroll to any element by selector query
```typescript jsx
const RedirectToHome = () => (
<Redirect path='/' position='#root' />
)
scrollFirst
When you use smooth scroll you can wait while the scrolling finished and then make the redirection.```typescript jsx const RedirectToHome = () => ( )
## Link
Use the component instance of `a`.
> `rel="noreferrer"` and `target="_blank"` are default for external links.
### href ![string](https://img.shields.io/badge/-string-green)
If `href` starts from `/` then the `Link` will use History API.
`/` is default value of `href`.
```typescript jsx
const App = () => (
<>
<div>
<Link>Home</Link>
<Link href='/test'>Test</Link>
</div>
<Router path='/'>Home</Router>
<Router path='/test'>Test</Router>
</>
)
When
href
starts from ?
the Link
will keep the pathname and change the search and hash.```typescript jsx const App = () => ( <>
<div>
<Link>Home</Link>
<Link href='/test'>Test</Link>
<Link href='?modal=test'>Test Modal</Link>
</div>
<Router path='/'>Home</Router>
<Router path='/test'>Test</Router>
<Router search='modal=test'><div>Test Modal</div></Router>
</>
)
When `href` starts from `#` the `Link` will keep the whole URL except for hash.
### replace ![boolean](https://img.shields.io/badge/-boolean-orange)
By default `Link` pushes to history but you may use `replace` to replace current history state.
```typescript jsx
const Agree = () => (
<Link replace href='?'>I agree</Link>
)
href='?'
means clearing of search and hashactiveClass
If you setactiveClass
then the link will have the class if url starts from href
```typescript jsx const Test = () => ( test )
When you click the link html will be equal
```html
<a class="active" href="/test">test</a>
exact
By defaultactiveClass
will be applied when url starts from href
but use exact
to compare exactly.```typescript jsx const Test = () => ( test )
### scrollTo ![number](https://img.shields.io/badge/-number-blue) ![string](https://img.shields.io/badge/-string-green)
If you wanna scroll the page to custom position (by default it's up of the page) use `scrollTo`
```typescript jsx
const To100 = () => (
<Link scrollTo={100} href='/test'>test</Link>
)
const ToRoot = () => (
<Link scrollTo='#root' href='/test'>test</Link>
)
Negative value keep the page on the same scroll position.
```typescript jsx const NoScroll = () => ( test )
### scrollFirst ![boolean](https://img.shields.io/badge/-boolean-orange)
When you use smooth scroll you can wait while the scrolling finished and then make the redirection.
```typescript jsx
const Test = () => (
<Link scrollFirst href='/test'>test</Link>
)
onMove
If you wanna wait for something before the move by the link then the property for you.```typescript jsx const Test = () => ( setTimeout(move, 100)}>test ) ```
links
- @watch-state/history-api - routing with History API
- package content