React和Redux:行动后重定向

时间:2017-03-23 19:37:31

标签: redux react-router

我开发了一个使用React / Redux的网站,我使用thunk中间件来调用我的API。我的问题涉及行动后的重定向。

我真的不知道如何以及在哪里可以进行重定向:在我的操作中,在reducer中,在我的组件中,...?

我的行动如下:

export function deleteItem(id) {
    return {
        [CALL_API]: {
            endpoint: `item/${id}`,
            method: 'DELETE',
            types: [DELETE_ITEM_REQUEST, DELETE_ITEM_SUCCESS, DELETE_ITEM_FAILURE]
        },
        id
    };
}

react-redux已在我的网站上实施,我知道我可以按照以下方式执行,但如果请求失败,我不想重定向使用:

router.push('/items');

谢谢!

7 个答案:

答案 0 :(得分:14)

绝对不要重定向你的reducer,因为它们应该是无副作用的。 看起来您正在使用api-redux-middleware,我认为它没有成功/失败/完成回调,我认为这对于库来说是非常有用的功能。

In this question from the middleware's repo,回购所有人建议这样的事情:

// Assuming you are using react-router version < 4.0
import { browserHistory } from 'react-router';

export function deleteItem(id) {
  return {
    [CALL_API]: {
      endpoint: `item/${id}`,
      method: 'DELETE',
      types: [
        DELETE_ITEM_REQUEST, 
        {
          type: DELETE_ITEM_SUCCESS,
          payload: (action, state, res) => {
            return res.json().then(json => {
              browserHistory.push('/your-route');
              return json;
            });
          },
        },
        DELETE_ITEM_FAILURE
      ]
    },
    id
  }
};

我个人更喜欢在我的连接组件的道具中有一个标志,如果是,则会路由到我想要的页面。我会像这样设置componentWillReceiveProps:

componentWillReceiveProps(nextProps) {
  if (nextProps.foo.isDeleted) {
    this.props.router.push('/your-route');
  }
}

答案 1 :(得分:7)

通常更好的做法是在组件中重定向,如下所示:

render(){
   if(requestFullfilled){
       router.push('/item')
   }
   else{
       return(
          <MyComponent />
       )
   }
}

答案 2 :(得分:1)

在Redux范围内必须使用react-redux-router push操作,而不是browserHistory.push

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

store.dispatch(push('/your-route'))

答案 3 :(得分:1)

最简单的解决方案

您可以使用react-router-dom版本* 5 + ,它实际上是在 react-router 内核之上构建的。

用法:

您需要从react-router-dom导入 useHistory 钩子,并将其直接传递给您的操作创建者函数调用。

导入和创建对象

import { useHistory } from "react-router-dom";

const history = useHistory();

组件中的操作调用:

dispatch(actionName(data, history));

动作创建者 现在,您可以在动作创建者中将历史记录对象作为函数参数来访问。

function actionName(data, history) {}

答案 4 :(得分:0)

我不希望重定向,而只是更改状态。您可能只是省略了已删除商品ID的结果:

// dispatch an action after item is deleted
dispatch({ type: ITEM_DELETED, payload: id })

// reducer
case ITEM_DELETED:
  return { items: state.items.filter((_, i) => i !== action.payload) }

答案 5 :(得分:0)

另一种方法是创建一个将您的重定向网址包含在其中的重定向函数:

const redirect = redirectUrl => {
  window.location = redirectUrl;
};

然后在分派后将其导入到您的操作中并返回;

return redirect('/the-url-you-want-to-redirect-to');

答案 6 :(得分:0)

import { useHistory } from "react-router-dom";
import {useEffect} from 'react';

const history = useHistory();

useEffect(()=>{
    // change if the user has successfully logged in and redirect to home 
    //screen
    if(state.isLoggedIn){
      history.push('/home');
    }
// add this in order to listen to state/store changes in the UI
}, [state.isLoggedIn])