如何在调度操作 Redux 后调用回调函数

问题描述 投票:0回答:5

我使用 React Redux 并创建了一个登录函数,但我需要在成功登录后获得回调返回并将用户重定向到页面。

我尝试将函数作为参数传递,但不起作用。

发货后如何获得退货?

Login fun
export const login = (request,cb) => {
           return dispatch => {
                let url = "/api/user/login";
                axios({
                    method: "post",
                    url: url,
                    data: request,
                    config: { headers: { "Content-Type": "multipart/form-data" } }
                })
                    .then(response => {
                        let authState = {
                            isLoggedIn: true,
                            user: response.data
                        };
                        cb();
                        window.localStorage["authState"] = JSON.stringify(authState);
                        return dispatch({
                            type: "USER_LOGIN_FULFILLED",
                            payload: { userAuthData: response.data }
                        });
                    })
                    .catch(err => {
                        return dispatch({
                            type: "USER_LOGIN_REJECTED",
                            payload: err
                        });
                    });
           };
    };

正在提交

handleLogin(e) {
        this.setState({ showLoader: true });
        e.preventDefault();
        const request = new Object();
        if (this.validator.allValid()) {
            request.email = this.state.email;
            request.password = this.state.password;
            this.props.login(request, () => {
                //get callbach here
                this.props.history.push('/my-space/my_views');
            })

            this.setState({ showLoader: false });

        } else {
            this.setState({ showLoader: false });
            this.validator.showMessages();
            this.forceUpdate();
        }
    }
const mapStateToProps = state => {
    return {
        authState: state
    };
};
const mapDispatchToProps = dispatch => {
    return {
        login: request => dispatch(login(request))
    };
};
export default connect(mapStateToProps, mapDispatchToProps)(LoginForm);
javascript reactjs redux callback
5个回答
2
投票

您的 connect(...) 中缺少 cb

这是修复方法

handleLogin(e) {
        this.setState({ showLoader: true });
        e.preventDefault();
        const request = new Object();
        if (this.validator.allValid()) {
            request.email = this.state.email;
            request.password = this.state.password;
            this.props.login(request, () => {
                //get callbach here
                this.props.history.push('/my-space/my_views');
            })

            this.setState({ showLoader: false });

        } else {
            this.setState({ showLoader: false });
            this.validator.showMessages();
            this.forceUpdate();
        }
    }
const mapStateToProps = state => {
    return {
        authState: state
    };
};
const mapDispatchToProps = dispatch => {
    return {
        login: (request, cb) => dispatch(login(request, cb))
    };
};
export default connect(mapStateToProps, mapDispatchToProps)(LoginForm);

希望有帮助:)


0
投票

如果您正在使用

redux-thunk
,您可以从您的
Promise
 返回 
async action

The function called by the thunk middleware can return a value,
that is passed on as the return value of the dispatch method.
In this case, we return a promise to wait for.
This is not required by thunk middleware, but it is convenient for us.

但我更喜欢使用

useEffect
componentDidUpdate
来达到此目的:

componentDidUpdate(){
  if(this.props.authState.isLoggedIn){
    this.props.history.push('/my-space/my_views');  
  }
}

0
投票

如果您需要具有回调功能的操作,我建议使用 Redux Cool 包。

安装

npm install redux-cool

使用方法

import {actionsCreator} from "redux-cool"


const my_callback = () => {
    console.log("Hello, I am callback!!!")
}

const callbackable_action = actionsCreator.CALLBACKABLE.EXAMPLE(1, 2, 3, my_callback)

console.log(callbackable_action)
//      {
//          type: "CALLBACKABLE/EXAMPLE",
//          args: [1, 2, 3],
//          cb: f() my_callback,
//          _index: 1
//      }

callbackable_action.cb()
//      "Hello, I am callback!!!"

当我们尝试生成一个动作对象时,我们可以将回调函数作为最后一个参数传递。

actionsCreator
将检查最后一个参数是否是一个函数,它将被视为回调函数。

请参阅Actions Creator了解更多详细信息


0
投票

react-redux/redux 调度返回一个承诺。如果您想返回一个值或在分派后确定请求是否成功/错误,您可以这样做

动作示例

export const fetchSomething = () => async (dispatch) => {
    try {
        const response = await fetchFromApi();
        dispatch({
            type: ACTION_TYPE,
            payload: response.value
        });
        return Promise.resolve(response.value);
    } catch (error) {
        return Promise.reject(error);
    }
}

用法

const foo = async data => {
    const response = new Promise((resolve, reject) => {
        dispatch(fetchSomething())
            .then(v => resolve(v)) 
            .catch(err => reject(err)) 
    });
    await response 
        .then((v) => navigateToSomewhere("/", { replace: true }))
        .catch(err => console.log(err));
};

这篇文章很旧,但希望能有所帮助

Package.json

   "react-redux": "^8.0.2"
   "@reduxjs/toolkit": "^1.8.5"

0
投票

将回调函数作为参数发送给动作创建者怎么样?它适用于我的登录逻辑。

组件:

  // inside the component
  const loginCallback = () => {
    history.push(location.state.referrer);
  };

  const handleLogin = (loginData) => {
    dispatch(loginActionCreator(loginData, loginCallback));
  };

动作创建者:

// inside the action creator

export const loginActionCreator =
  (loginData, loginCallback) => (dispatch, getState) => {
    dispatch({
      type: userActions.setFetchState,
      payload: FETCH_STATES.FETCHING,
    });
    doSRRequest(srEndpoints.login(loginData))
      .then((res) => {
        dispatch({
          type: userActions.setUser,
          payload: res,
        });
        dispatch({
          type: userActions.setFetchState,
          payload: FETCH_STATES.FETHCED,
        });
        loginCallback();
      })
  };



© www.soinside.com 2019 - 2024. All rights reserved.