无法在 redux 操作中执行异步操作

Posted

技术标签:

【中文标题】无法在 redux 操作中执行异步操作【英文标题】:Can't do async in redux action 【发布时间】: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 没有意义 【参考方案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())

以上是关于无法在 redux 操作中执行异步操作的主要内容,如果未能解决你的问题,请参考以下文章

Redux工具包 - Redux Toolkit的异步操作(发送网络请求)

如何使用 redux-axios-middleware 测试 Redux 异步操作

在使用 Redux-Thunk 异步操作的 Promise 链中使用 setInterval

使用 typescript 将异步操作发送到 redux 调度

在 redux 中处理异步操作错误的最佳实践是啥?

请求完成后触发 Redux 异步操作。为啥?