React Router BrowserHistory.push Open Link In A New Tab
Solution 1:
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".
Solution 2:
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.
Solution 3:
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.
Solution 4:
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
Post a Comment for "React Router BrowserHistory.push Open Link In A New Tab"