Navigation
Found provides a high-level abstractions such as a link component for controlling browser navigation. Under the hood, it delegates to Farce for implementation, and as such can also be controlled directly via the Redux store.
Links
The <Link>
component renders a link with optional active state indication.
const link1 = (
<Link to="/widgets/foo" activeClassName="active">
Foo widget
</Link>
);
const link2 = (
<Link
as={CustomAnchor}
to={{
pathname: "/widgets/bar",
query: { the: query },
}}
activePropName="active"
>
Bar widget with query
</Link>
);
const link3 = (
<Link
to={{
pathname: "/widgets/bar",
query: { the: query },
}}
>
{({ href, active, onClick }) => (
<CustomButton href={href} active={active} onClick={onClick} />
)}
</Link>
);
<Link>
accepts the following props:
to
: a location descriptor for the link's destinationexact
: if specified, the link will only render as active if the current location exactly matches theto
location descriptor; by default, the link also will render as active on subpaths of theto
location descriptoractiveClassName
: if specified, a CSS class to append to the component's CSS classes when the link is activeactiveStyle
: if specified, a style object to append merge with the component's style object when the link is activeactivePropName
: if specified, a prop to inject with a boolean value with the link's active stateas
: if specified, the custom element type to use for the link; by default, the link will render an<a>
element
A link will navigate per its to
location descriptor when clicked. You can prevent this navigation by providing an onClick
handler that calls event.preventDefault()
.
<Link>
accepts a function for children
. If children
is a function, then <Link>
will render the return value of that function, and will ignore activeClassName
, activeStyle
, activePropName
, and as
above. The function will be called with an object with the following properties:
href
: the URL for the linkactive
: whether the link is activeonClick
: the click event handler for the link element
Otherwise, <Link>
forwards additional props to the child element.
Programmatic navigation
The withRouter
HOC wraps an existing component class or function and injects match
and router
props, as on route components above. You can use this HOC to create components that navigate programmatically in event handlers.
class MyButton extends React.Component {
onClick = () => {
this.props.router.replace("/widgets");
};
render() {
return (
<button onClick={this.onClick}>
Current widget: {this.props.match.params.widgetId}
</button>
);
}
}
export default withRouter(MyButton);
The useRouter
Hook provides the same capabilities.
function MyButton() {
const { match, router } = useRouter();
const onClick = useCallback(() => {
router.replace("/widgets");
}, [router]);
return (
<button onClick={onClick}>
Current widget: {match.params.widgetId}
</button>
);
}
Blocking navigation
The router.addNavigationListener
method adds a navigation listener that can block navigation. This method accepts a navigation listener function and an optional options object. It returns a function that removes the navigation listener.
function MyForm(props) {
const [dirty, setDirty] = useState(false);
const { router } = useRouter();
useEffect(
() =>
dirty
? router.addNavigationListener(
() =>
"You have unsaved input. Are you sure you want to leave this page?"
)
: undefined,
[dirty]
);
/* ... */
}
The navigation listener function receives the location to which the user is attempting to navigate as its argument. Return true
or false
from this function to allow or block navigation respectively. Return a string to display a default confirmation dialog to the user. Return a nully value to use the next navigation listener if present, or else allow navigation. Return a promise to defer allowing or blocking navigation until the promise resolves; you can use this to display a custom confirmation dialog.
If you want to run your navigation listeners when the user attempts to leave the page, set beforeUnload
in the options object. If this option is enabled, your navigation listeners will be called with a null
location when the user attempts to leave the page. In this scenario, the navigation listener must return a non-promise value.
router.addNavigationListener(
(location) => {
if (!location) {
return false;
}
return asyncConfirm(location);
},
{ beforeUnload: true }
);
The navigation listener usage example demonstrates the use of navigation listeners in more detail, including the use of the beforeUnload
option.