使用 React-Router 4 和 Redux-Promise 重定向用户

Posted

技术标签:

【中文标题】使用 React-Router 4 和 Redux-Promise 重定向用户【英文标题】:Redirect user with React-Router 4 and Redux-Promise 【发布时间】:2018-02-18 16:09:21 【问题描述】:

我有一个简单的用例,在 React-Router 4 和 Redux 环境中似乎很难实现。

当用户登录时,会触发 redux 承诺操作,该操作会返回 API 令牌、到期日期和其他一些信息。何时以及如果实现了承诺,我希望将用户重定向到另一个页面。

我无法弄清楚如何使用上述架构以编程方式重定向用户。想在Action.js里面做,但是感觉只能在Reducers.js里面做。即使我不确定如何开始。

到目前为止,我发现的最佳方法是在我的视图中添加一个 Redirect 组件,并让 promise 将 loggedIn 状态设置为 true,如果该视图上的 loggedIn 道具为 true,它将返回重定向道具,然后将用户重定向到所需的页面。不知何故,这感觉像是一个简单用例的大量额外代码。

任何建议都会有所帮助。谢谢。

Action.js:

import axios from 'axios';

export function login(email, password) 
  return 
    type: 'LOGIN_USER',
    payload: axios.post('http://localhost:3114/api/users/authenticate', 
    
      email,
      password,
    ),
  ;

Reducers.js

// Promise
// pending
// fulfilled
// rejected
const initalState = 
  token: null,
  expiryDate: '',
  loading: false,
  error: null,
;

// REDCUER
function loginReducer(state = initalState, action) 
  switch (action.type) 
    case 'LOGIN_USER_PENDING':
      return  ...state, loading: true ;
    case 'LOGIN_USER_FULFILLED':
      return 
        ...state,
        loading: false,
        token: action.payload.data.token,
        expiryDate: action.payload.data.expires,
        loggedIn: true,
      ;
    case 'LOGIN_USER_REJECTED':
      return  ...state, loading: false, error: `$action.payload` ;
    default:
      return state;
  


export default loginReducer;

LoginView.js

render() 
        const  data, login, loggedIn  = this.props;
        if (data.loggedIn) 
          return <Redirect to="/users" push />;
        
        return (
          ...
        )
       

问候, 埃米尔

【问题讨论】:

像我建议的那样,history.push 运气好吗? @jonahe 感谢您的跟进。一天之内就会告诉你。目前正在处理 3 个项目,有点杂耍。 【参考方案1】:

我可以看到 Redux 状态中的 isLoggedIn 可能在以后有用(例如,您可以将所有应该只对登录用户可见的路由/页面包装在一个检查此 isLoggedIn 的组件中并可能重定向到登录页面),所以我不一定会在那里改变任何东西。

但如果您仍想找到另一种解决方法,则可以使用history.push(newUrl) or history.replace(newUrl) 以编程方式重定向(无需渲染重定向组件)。但我不确定你会在哪里称呼它。与在 reducer 中相比,在动作创建器中出现副作用对我来说似乎稍微不那么奇怪,所以一种可能性可能是做类似

的事情
import axios from 'axios';

// pushOnResolve would be something like () => push('mynew/url')
export function login(email, password, pushOnResolve) 
  const promise = axios.post('http://localhost:3114/api/users/authenticate';
  // it's possible to have several .then on a promise
  // so this shouldn't interfere with
  // the Redux-promise or the LOGIN_USER_FULFILLED reducer
  promise.then(pushOnResolve);

  return 
    type: 'LOGIN_USER',
    payload: promise, 
    
      email,
      password,
    ),
  ;

【讨论】:

以上是关于使用 React-Router 4 和 Redux-Promise 重定向用户的主要内容,如果未能解决你的问题,请参考以下文章

使用react,react-router和redux进行分页

利用 React/Redux/React-Router 4/webpack 开发大型 web 项目时如何按需加载

如何用 redux 和 react-router 组织状态?

使用 React-Router 和 Redux 时单击链接时如何调度操作?

Redux 和 React-Router:动态路由器不工作

如何使用 React-Router 和 React-Redux 将道具发送到子路由组件?