React Router browserHistory.push在新选项卡中打开链接

时间:2016-06-23 16:44:55

标签: javascript reactjs react-router

可以使用<link>作为

<Link to="route" target="_blank">

在新标签页中打开链接。但是可以使用browserHistory.push在新标签中打开链接吗?

4 个答案:

答案 0 :(得分:6)

React-router基于浏览器History API构建。   private async void AddCookBook_Click(object sender, RoutedEventArgs e) { CookBookDialog newCookBookDialog = new CookBookDialog(); newCookBookDialog.PrimaryButtonClick += NewCookBookDialog_PrimaryButtonClick; newCookBookDialog.Opened += NewCookBookDialog_Opened; newCookBookDialog.Closed += NewCookBookDialog_Closed; await newCookBookDialog.ShowAsync(); } private void NewCookBookDialog_Closed(ContentDialog sender, ContentDialogClosedEventArgs args) { textBlock.Text = "Closed"; } private void NewCookBookDialog_Opened(ContentDialog sender, ContentDialogOpenedEventArgs args) { textBlock.Text = "Open"; } private void NewCookBookDialog_PrimaryButtonClick(ContentDialog sender, ContentDialogButtonClickEventArgs args) { p_App.DataBase.CookBooks.Add(((CookBookDialog)sender).CookBook); } private async void CreateRecipe_Click(object sender, RoutedEventArgs e) { RecipeDialog newRecipeDialog = new RecipeDialog(); newRecipeDialog.PrimaryButtonClick += NewRecipeDialog_PrimaryButtonClick; await newRecipeDialog.ShowAsync(); } 调用pushState()方法。

从链接文档的第一行开始:

  

pushState()有三个参数:状态对象,标题(当前被忽略)和(可选)统一资源定位符(URL)。

所以,你的问题的答案是“不”。

答案 1 :(得分:0)

我一直在抱怨一个小时,直到看到库珀的评论

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/ 我之所以没有添加它,是因为浏览器希望用户在我这样做时明确允许弹出窗口。

答案 2 :(得分:0)

基于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键。将所有存在useHistory.push的实例替换为useCtrlHistory.push,它将检测到ctrl键按下。

答案 3 :(得分:-1)

从react_router 1.0开始,道具将被传递到锚标签。您可以直接使用target =“_ blank”。这里讨论:https://github.com/ReactTraining/react-router/issues/2188