繁体   English   中英

如何在单击按钮时等待异步操作分派?

[英]How can I await for an async action dispatch on the click of a button?

我有这个反应组件,用户想要发送登录请求,但每当我分派操作时,甚至在它执行之前,我的组件中的进一步代码就会被执行。

我试过将登录请求 function 设为async ,甚至尝试在分派操作之前使用 await,但这一切都是徒劳的。

组件文件:

import React from 'react';
import BaseButton from '../BaseButton/BaseButton';
import { useState } from 'react';
import { userLogin } from '../../redux/auth/authActions';
import axios from 'axios';
import {connect} from 'react-redux'

function Login({ isLoggedIn, userLogin }) {
  const [login, setLogin] = useState(true); //to see if the user wats to login or sign up
  const [email, setEmail] = useState("");
  const [name, setName] = useState("");
  const [password, setPassword] = useState("");
  const [confirmPassword, setConfirmPassword] = useState("");

  const handleLogin = () => {
    let userCredentials = {
      email: email,
      password: password
    }
        
    userLogin(userCredentials);   // <------ i want to wait for this to execute before the below code is executed

    if (isLoggedIn) {
      console.log('im here');
    } else {
      console.log('wrong credentials');
    }
  }

  const handleSignUp = async () => {

  }

  return login ? (
    <> 
      {*/ ...some JSX for user input */}

          <div className="flex justify-center">
            <BaseButton variant={'solid'} onClick = {handleLogin}>Submit</BaseButton>
          </div>

      {*/ ...some more JSX for user input */}
    <>
}

const mapStateToProps = (state) => {
  return {
    isLoggedIn: state.auth.isLoggedIn
  }
}

const dispatchStateToProps = (dispatch) => {
  return {
    userLogin: (userCredentials) => dispatch(userLogin(userCredentials))
  }
}

export default connect(mapStateToProps, dispatchStateToProps)(Login);

授权操作:

import {
  USER_LOGIN_REQUEST,
  USER_LOGIN_SUCCESS,
  USER_LOGIN_FAILURE,
} from './authTypes';
import axios from 'axios';

export const sendLoginRequest = () => {
  return {
    type: USER_LOGIN_REQUEST,
  };
};

export const loginSucccess = () => {
  return {
    type: USER_LOGIN_SUCCESS,
  };
};

export const loginFailure = (error) => {
  return {
    type: USER_LOGIN_FAILURE,
    payload: error,
  };
};

export const userLogin = (userCredentials) => {
  return (dispatch) => {
    try {
      dispatch(sendLoginRequest());
      axios
        .post('http://localhost:3001/auth/login', userCredentials)
        .then((data) => {
          console.log(data.status);
          dispatch(loginSucccess());
        })
        .catch(err => {
          console.log("incorrect credentials");
          dispatch(loginFailure('incorrect credentials'));
        });
    } catch(err) {
      dispatch(loginFailure(err.message));
    }
  };
};

授权减速器文件:

import {
  USER_LOGIN_REQUEST,
  USER_LOGIN_FAILURE,
  USER_LOGIN_SUCCESS,
} from './authTypes';

const initialState = {
  loading: false,
  isLoggedIn: false,
  error: ''
};

const authReducer = (state = initialState, action) => {
  switch (action.type) {
    case USER_LOGIN_REQUEST:
      return {
        ...state,
        loading: true
      }
    case USER_LOGIN_SUCCESS: return{
        ...state,
        loading: false,
        isLoggedIn: true,
    }
    case USER_LOGIN_FAILURE: return{
        ...state,
        loading: false,
        isLoggedIn: false,
        error: action.payload
    }
    default: return state;
  }
};

export default authReducer;

我的商店文件:

import { createStore, applyMiddleware } from 'redux';
import { composeWithDevTools } from 'redux-devtools-extension';
import thunk from 'redux-thunk';
import rootReducer from '../rootReducer';

const store = createStore(rootReducer, composeWithDevTools(applyMiddleware(thunk)));

export default store;

根减速器:

import {combineReducers} from 'redux';
import authReducer from './auth/authReducer';

const rootReducer = combineReducers({
  auth: authReducer
});

export default rootReducer;

userLogin操作未声明为async ,也未返回 Promise,因此这就是您的handleLogin处理程序无法等待它完成的原因。

userLogin转换为async操作 function。

export const userLogin = (userCredentials) => async (dispatch) => {
  try {
    dispatch(sendLoginRequest());
    const data = await axios.post('http://localhost:3001/auth/login', userCredentials);

    console.log(data.status);

    dispatch(loginSucccess());

    return true; // <-- return resolved value
  } catch(err) {
    dispatch(loginFailure(err.message));
    return false; // <-- return resolved value
  }
};

handleLogin转换为async function 以便它可以await分派的操作来解决。 请注意, handleLogin不会,看不到来自 Redux 的任何更新的isLoggedIn state 值,而它的当前值从调用时起已在 scope 中关闭。

const handleLogin = async () => {
  const userCredentials = { email, password };
        
  const authSuccess = await userLogin(userCredentials);

  if (authSuccess) {
    console.log('I'm here');
  } else {
    console.log('wrong credentials');
  }
};

使用 async await 或 catch in handleLogin function 并且不要忘记在 userLogin 和子函数中添加 return

`const handleLogin = async () => {
    await userLogin(userCredentials); 
    if(isLoggedIn) {
       console.log('here');
    }
}`

或然后使用

`userLogin(userCredentials).then(() => { if(isLoggedIn){
          console.log('here');
}});`

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM