Interceptable Link
Opened this issue · 2 comments
I use the Link
component and it's awesome. But there's no way I can intercept that click.
In particular, depending on some programmatic logic I'd like to do some things in the onClick
that may or may not cancel the click. For example:
<Link
view={views.podcast}
params={{id: podcast.id, slug: podcast.slug}}
store={store}
// pseudo code!
onClick={e => {
if (someCondition) {
store.app.something = 'foo'
return false
}
}}
>
Click Here
</Link>
It's always a bit weird to have multiple onClick
events because it's confusing what the order is supposed to be.
Here's a hack I wrote for my own needs. This works well:
export const InterceptableLink = ({
view,
className,
params = {},
queryParams = {},
store = {},
refresh = false,
style = {},
children,
title = children,
router = store.router,
onClick = null, // THIS IS NEW
}) => {
if (!router) {
return console.error('The router prop must be defined for a Link component to work!')
}
return (<a
style={style}
className={className}
onClick={e => {
// THESE LINES ARE NEW
if (onClick && onClick(e) === false) {
e.preventDefault();
return;
}
// END NEW LINES
const middleClick = e.which === 2;
const cmdOrCtrl = (e.metaKey || e.ctrlKey);
const openinNewTab = middleClick || cmdOrCtrl;
const shouldNavigateManually = refresh || openinNewTab || cmdOrCtrl;
if (!shouldNavigateManually) {
e.preventDefault();
router.goTo(view, params, store, queryParams);
}
}}
href={view.replaceUrlParams(params, queryParams)}>
{title}
</a>
)
}
Do you think that's a good idea? If so, I can clean it up in the form of a PR.
By the way, here's why I think it's an awesome idea.
I have a tabular page. It does an AJAX query (e.g. /api/items/?page=1
). If you click on one of them, it goes to the "perma page" for that item. Then, to get the data it does an AJAX query again (e.g. /api/items?id=1234
and something like...
.then(result => {
store.app.item = result.items[0]
})
(It also loads other stuff that isn't displayed in the tabular page)
So by intercepting the click, from the tabular page, I can do this:
<InterceptableLink
view={views.podcast}
params={{id: podcast.id, slug: podcast.slug}}
store={store}
onClick={e => {
store.app.podcast = podcast // <--- here lies the magic!
}}
>
<img src={imageURL} role="presentation" className="rounded"/>
</InterceptableLink>
That means that when the perma page loads, the data will already have been put in the store and thus it loads instantaneous!
Ah, this looks really interesting. Will take a stab at it soon! 🙌