Reputation: 36219
It is possible to use <link>
as
<Link to="route" target="_blank">
to open links in new tab. But is it possible to use browserHistory.push
to open links in a new tab?
Upvotes: 9
Views: 17937
Reputation: 1
Building on David's answer, this can be accomplished by wrapping the useHistory hook in a custom one. I renamed mine 'useCtrlHistory' and have this:
import {useEffect, useState} from 'react';
import {useHistory} from "react-router";
export default () => {
const [ctrlKeyPressed, setCtrlKeyPressed] = useState(false);
const handleKeyDown = e => {
if (e.ctrlKey) {
setCtrlKeyPressed(true);
}
};
const handleKeyUp = e => {
if (!e.ctrlKey) {
setCtrlKeyPressed(false);
}
};
const history = useHistory();
let ctrlHistory = Object.assign({}, history, {
push: (value) => {
if (ctrlKeyPressed) {
window.open(value);
} else {
history.push(value);
}
}
});
useEffect(() => {
document.addEventListener('keydown', handleKeyDown);
document.addEventListener('keyup', handleKeyUp);
window.addEventListener('blur', handleKeyUp);
return () => {
document.removeEventListener('keydown', handleKeyDown);
document.removeEventListener('keyup', handleKeyUp);
window.removeEventListener('blur', handleKeyUp);
};
}, []);
return ctrlHistory;
};
This will create a new hook that listens for the ctrl key to be pressed. Replace any instances where useHistory.push is present with useCtrlHistory.push and it will detect the ctrl key down.
Upvotes: 0
Reputation: 636
I've been grouching about it for an hour until I saw Cooper's comment
browserHistory is per tab.
which is so simple but accurate, and made me come up with this solution:
I put it in my App.js (UPDATE: I've added the window blur
event because I've encountered a missing keyUp event when cmd+tab or cmd+` to another window.)
const [metaKeyPressed, setMetaKeyPressed] = useState(false);
const handleMetaKeyDown = e => {
if (e.metaKey) {
setMetaKeyPressed(true);
}
};
const handleMetaKeyUp = e => {
if (e.metaKey) {
setMetaKeyPressed(false);
}
};
useEffect(() => {
document.addEventListener('keydown', handleMetaKeyDown);
document.addEventListener('keyup', handleMetaKeyUp);
window.addEventListener('blur', handleMetaKeyUp);
return () => {
document.removeEventListener('keydown', handleMetaKeyDown);
document.removeEventListener('keyup', handleMetaKeyUp);
window.removeEventListener('blur', handleMetaKeyUp);
};
});
Then I have metaKeyPressed
which I use to select whether to history.push
or window.open
(simplified for readability):
const handleRoute = path => {
if (metaKeyPressed) {
window.open(path);
} else {
history.push(path);
}
};
Also, Consider adding a fix for this issue https://www.jitbit.com/alexblog/256-targetblank---the-most-underestimated-vulnerability-ever/ I haven't not add this because the browser wants the user to explicitly allow popups when I do.
Upvotes: 1
Reputation: 6978
React-router is build on the browser History API.
browserHistory.push
calls pushState()
method.
From the first line of the linked document:
pushState( ) takes three parameters: A state object, a title (which is currently ignored), and (optionally) a Uniform Resource Locator (URL).
So, the answer to your question is "No".
Upvotes: 10
Reputation: 1554
Starting with react_router 1.0, the props will be passed onto the anchor tag. You can directly use target="_blank". Discussed here: https://github.com/ReactTraining/react-router/issues/2188
Upvotes: -3