Redux:从API成功响应后打开外部URL

时间:2016-07-01 10:42:20

标签: reactjs redux react-router-redux

我想在收到来自api的成功回复后使用生成的url打开一个url。我试图在减速器内打开这个url:

window.open(url, '_blank');

这似乎适用于大多数浏览器,但在safari中不兼容。

任何想法如何实现跨浏览器兼容?有没有办法用react-router-redux做到这一点?

谢谢!

更新:我需要打开一个外部网址,而不是项目中的路由,所以可能是react-router不是解决方案

3 个答案:

答案 0 :(得分:5)

根据官方的redux文档,在减速器中你不应该:

  • 改变其论点;
  • 执行API调用和路由等副作用 转换
  • 调用非纯函数,例如Date.now()或 的Math.random()。

如果您使用redux-thunk中间件来发出api请求,那么最好在那里执行重定向。

例如:

// actions.js

function asyncApiCall() {
  return function (dispatch) {
    return fetch('/api')
      .then(response => response.json().then(body => ({ response, body })))
      .then(({ response, body }) => {
        if (response.ok) {
          window.open(url, '_blank');
        }
      });
  };
}

答案 1 :(得分:3)

Reducers应该是纯粹的,因此你不应该尝试在那里打开一个新窗口,而应该为你的所有获取请求创建一个中间件,然后在成功的请求中你可以重定向,打开模态和你需要的任何东西,例如:

import { push } from 'react-router-redux';

export default fetchMiddleware() {
 return ({ dispatch, getState }) => next => action => {
   if (!action.fetch) {
     return next(action);
   }

   const promise = fetch(action.fetch, { someOptionsHere })
     .then(response => response.json())
     .then(data => {
       if (whateverLogicYouNeedToRedirect) {
          return next(push('/go/somewhere/else'));
       }
       next({type: action.type, response: data});
     })
     .catch( error => {
        // check for errors in the response and
        // maybe redirect to login here
        next({type: 'FETCH_FAIL', error });
     });

   return promise;
 };
}

这是一个简单的中间件,它从您的API获取数据,然后解析JSON响应,然后根据您的逻辑,它可以重定向到不同的URL或只返回带有获取响应的操作,您将使用此中间件来自你的动作创作者:

 export function loadData() {
   return {
     type: 'LOAD_SOMETHING',
     fetch: '/api/something/here',
   };
 }

你应该改进中间件以接受params,一种定义postputdelete请求以及你需要的任何其他内容的方法,但我希望这会给你一个想法。

答案 2 :(得分:2)

  

允许在中打开新窗口的唯一javascript   Safari / Chrome是javascript直接附加到点击处理程序(和   其他直接用户输入处理程序)。在过去的版本中人们想通了   一些欺骗的方法(比如生成一些其他元素 - 一种形式或   div - 并使用javascript模拟用户输入),但更新的版本   更聪明地发现这一点。

并且你不应该在reducers中包含这个逻辑。

也许弹出一些模态并提供给用户点击按钮。 您可以在收到数据后通过调度操作类型{type:" OPEN_MODAL"}

执行此操作