【问题标题】:Can't do async in redux action无法在 redux 操作中执行异步操作
【发布时间】:2017-06-23 02:55:39
【问题描述】:

我已经使用 redux thunk 来做异步。它已经可以使用这种格式了:

export function registerUser({email,password}){
    return function(dispatch){
        axios.post(`${ROOT_URL}/api/auth/signup`,{email,password})
            .then(response =>{
                dispatch({type:AUTH_USER});
                localStorage.setItem('laravel_user_token',response.data.token);
                browserHistory.push('/register');
            })
            .catch(response => dispatch(authError(response.data.error)));
    }
}

现在我想尝试在注销时执行一些异步操作,如下所示:

export function logoutUser() {
    console.log("logout");
    localStorage.removeItem('laravel_user_token');
    return { type: LOGOUT_USER }
}

这是工作,现在我打算在使用此代码执行注销后重定向页面:

export function logoutUser() {
    return dispatch => {
        console.log("logout");
        localStorage.removeItem('laravel_user_token');
        return dispatch({ type: LOGOUT_USER })
        .then(() => 
            browserHistory.push("/")
        );
    }
}

我的问题是没有回复,甚至我的 console.log("logout") 也不起作用。

【问题讨论】:

  • return dispatch({ type: LOGOUT_USER }) .then(() => browserHistory.push("/") ); 这不起作用,因为 dispatch 在这里没有返回承诺,所以 .then 没有意义

标签: reactjs asynchronous redux react-router redux-thunk


【解决方案1】:

您可以通过一些变体来执行它。

1。通过承诺

正如您尝试的那样,这是使用 Promise 执行的,所以您的 main 错误 - 您的函数没有返回 Promise

改变你的行动

export function logOut() {
 return (dispatch) =>  {
  return new Promise((resolve) => { 
      dispatch({
         type    : LOGOUT_USER,
      });

      resolve();
  }
}

你的动作处理器可以是简单的reducer函数,它会改变状态。

case 'LOGOUT_USER' : (state) =>  {
  return Object.assign({}, state, {
    autenticated : false
  })
}

然后,从 react 组件中调用它。

hireLogoutClick = () => {
   this.props.logOut().then(() => browserHistory.push('/');
}

logOut 函数返回Promise,它将在resolve() 步骤调用您的回调函数。首先会调用你的 reducer 函数,然后会调用你的回调函数(函数传入.then


2。通过中间件

还有另一种变体,如何通过中间件执行此操作,并从 reducer 调用它,就像一个动作一样,中间件会捕获它并重定向,我认为更好,然后使用 Promise。

创建中间件

import { browserHistory } from 'react-router'
import { ROUTING } from '../constants/ActionTypes'

 export const redirect = store => next => action => {  
    if(action){
       if (action.type === ROUTING) {
         browserHistory['push'](action.nextUrl)
     }
  }

   return next(action)
 }

绑定一下

// Apply the middleware to the store
const middleware = routerMiddleware(browserHistory)
const store = createStore(
  reducers,
  applyMiddleware(middleware)
)

使用:)

export function logOut () {
    return (dispatch) =>  {
      dispatch({
         type    : types.LOGOUT_USER
      })

      dispatch({
         type : types.ROUTING,
         nextUrl: '/'
     })
   }
  }

【讨论】:

  • 我怎么能在我的减速器中添加objectAssign({}, state, {authenticated: false});呢?我试试这个代码:case 'LOGOUT_USER' : (state) => { objectAssign({}, state, {authenticated: false}); return dispatch({ type: LOGOUT_USER }).then(() => browserHistory.push("/") ); }。你能帮我修复代码@Dmitriy Kovalenko
  • 更新,包括改变状态的例子
  • 我把return dispatch({ type: LOGOUT_USER }).then(() => browserHistory.push("/") );放在哪里,因为在reducer中已经返回objectAssign({}, state, {authenticated: true});@Dmitriy Kovalenko
  • 你调用action => logoutUser,它返回Promise,并调用你的reducer,它会更新你的状态,然后,action解决promise,并调用回调
  • 你从你的 react 组件调用 dispatch(logOut())
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-03-20
  • 2020-04-23
  • 2016-06-02
  • 2016-11-10
  • 1970-01-01
  • 1970-01-01
  • 2017-09-26
相关资源
最近更新 更多