[英]React Router browserHistory.push open link in a new tab
可以使用<link>
作为
<Link to="route" target="_blank">
在新标签页中打开链接。 但是是否可以使用browserHistory.push
在新选项卡中打开链接?
React-router 是建立在浏览器历史 API 之上的。 browserHistory.push
调用pushState()
方法。
从链接文档的第一行:
pushState() 接受三个参数:状态对象、标题(当前被忽略)和(可选)统一资源定位符(URL)。
所以,你的问题的答案是“不”。
我已经抱怨了一个小时,直到我看到 Cooper 的评论
browserHistory 是每个标签。
这非常简单但准确,让我想出了这个解决方案:
我把它放在我的 App.js 中(更新:我添加了窗口blur
事件,因为当 cmd+tab 或 cmd+` 到另一个窗口时我遇到了一个缺少的 keyUp 事件。)
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);
};
});
然后我有metaKeyPressed
,我用它来选择是history.push
还是window.open
(为了可读性而简化):
const handleRoute = path => {
if (metaKeyPressed) {
window.open(path);
} else {
history.push(path);
}
};
另外,考虑为这个问题添加一个修复https://www.jitbit.com/alexblog/256-targetblank---the-most-underestimated-vulnerability-ever/我没有添加这个,因为浏览器想要用户当我这样做时明确允许弹出窗口。
基于 David 的回答,这可以通过将 useHistory 钩子包装在自定义钩子中来实现。 我将我的“useCtrlHistory”重命名为:
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;
};
这将创建一个新的钩子来监听要按下的 ctrl 键。 用 useCtrlHistory.push 替换任何存在 useHistory.push 的实例,它将检测到 ctrl 键按下。
从 react_router 1.0 开始,props 将被传递到锚标签上。 您可以直接使用 target="_blank"。 在这里讨论: https : //github.com/ReactTraining/react-router/issues/2188
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.