无法在 redux 操作中执行异步

Can't do async in redux action

我已经使用 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")都不行。

执行它有一些变体。

1.通过承诺

按照您尝试的方式,这是使用 Promise 执行的,因此您的 main 错误 - 您的函数不是 returning 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
  })
}

然后,从反应组件中调用它。

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

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


2。通过中间件

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

创建中间件

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: '/'
     })
   }
  }