Axios请求不适用于React + Redux

时间:2019-06-04 22:03:56

标签: node.js reactjs redux react-redux

我会尝试给出一个前提,然后再跟上代码。

我决定在我的React项目中实现Material UI,并且大部分工作都在进行中。如何设置应用程序,用户将面临“登录”页面。 Login.js模块呈现SignIn.js module,输入其凭据,然后单击提交。 formDataonChangeonSubmit作为道具从登录组件传递到SignIn组件-并且Login组件通过mapStateToProps接收它们。 Login组件使用connect中间件将redux状态链接到react应用。

单击提交会触发formData(在Login组件中,传递到SignIn组件中)击中位于login的{​​{1}}方法。错误是从此方法内部发生的,在try catch的axios调用处,我尝试与后端"../../actions/auth";

通信

奇怪的是const response = await axios.post("/api/auth", body, config);从未被击中,这应该将状态设置为从后端返回的令牌,因为似乎从未执行过dispatch({ type: LOGIN_SUCCESS, payload: response.data });。但是非常奇怪的是,控制台记录令牌的实际工作原理!似乎它从未存储过,从而强制调用AUTH_ERROR。

这是我的登录组件:

LOGIN_SUCCESS

它正在呈现的SignIn组件在这里:

 // Login.js
 import SignIn from "../../material/SignIn";

 const Login = ({ setAlert, login, isAuthenticated }) => {
 const [formData, setFormData] = useState({
 email: "",
 password: ""
 });

 const { email, password } = formData;

 const onChange = e => {
 setFormData({ ...formData, [e.target.name]: e.target.value });
 };

 const onSubmit = e => {
 login(email, password);
 };
 // Redirect if logged in
 if (isAuthenticated) {
 return <Redirect to="/dashboard" />;
 }

 return (
 <Fragment>
      <SignIn
      email={email}
      password={password}
      onSubmit={onSubmit}
      onChange={onChange}
      isAuthenticated={isAuthenticated}
      />
 </Fragment>
 );
 };

 Login.propTypes = {
 setAlert: PropTypes.func.isRequired,
 login: PropTypes.func.isRequired,
 isAuthenticated: PropTypes.bool
 };

 const mapStateToProps = state => ({
 isAuthenticated: state.auth.isAuthenticated
 });

 export default connect(
 mapStateToProps,
 { setAlert, login }
 )(Login);

单击“提交”按钮将在我的“登录”组件中引发 // SignIn.js export default function SignIn({ email, password, onChange, onSubmit }) { const classes = useStyles(); return ( <Container component="main" maxWidth="xs"> <CssBaseline /> <div className={classes.paper}> <Avatar className={classes.avatar}> <LockOutlinedIcon /> </Avatar> <Typography component="h1" variant="h5"> Sign in </Typography> <form onSubmit={e => onSubmit(e)} className={classes.form} noValidate> <TextField variant="outlined" margin="normal" required onChange={e => onChange(e)} fullWidth id="email" label="Email Address" name="email" value={email} // autoComplete="email" autoFocus /> <TextField variant="outlined" margin="normal" required onChange={e => onChange(e)} fullWidth name="password" label="Password" type="password" value={password} id="password" autoComplete="current-password" /> <FormControlLabel control={<Checkbox value="remember" color="primary" />} label="Remember me" /> <Button type="submit" fullWidth variant="contained" color="primary" className={classes.submit} > Sign In </Button> <Grid container> <Grid item xs> <Link href="#" variant="body2"> Forgot password? </Link> </Grid> <Grid item> <Link href="#" variant="body2"> {"Don't have an account? Sign Up"} </Link> </Grid> </Grid> </form> </div> <Box mt={5}> <MadeWithLove /> </Box> </Container> ); } 方法:

onSubmit

如果您注意到在axios调用之后, // Login user export const login = (email, password) => async dispatch => { // Config needed because we're sending data const config = { headers: { "Content-Type": "application/json" } }; const body = JSON.stringify({ email, password }); try { const response = await axios.post("/api/auth", body, config); // Skips over this dispatch dispatch({ type: LOGIN_SUCCESS, payload: response.data }); // But hits this dispatch.. and then console logs 'REACHED' as seen below dispatch(loadUser()); } catch (err) { const errors = err.response.data.errors; if (errors) { errors.forEach(error => { dispatch(setAlert(error.msg, "danger")); }); } dispatch({ type: LOGIN_FAIL }); } }; 定义为:

loadUser is called

后端路由如下:

 // Load user
 export const loadUser = () => async dispatch => {
 const token = localStorage.token;

 console.log('REACHED!'); // reached

 if (token) {
 setAuthToken(token);
 }

 try {
 const response = await axios.get("/api/auth");

 dispatch({
      type: USER_LOADED,
      payload: response.data
 });
 } catch (err) {
 dispatch({
      type: AUTH_ERROR // This is dispatched
 });
 }
 };

我现在很困惑。令牌已被渲染,但似乎React在Node有机会将其发回之前并未“等待”响应。

1 个答案:

答案 0 :(得分:0)

不确定如何解释这一点,但是我通过摆脱form标记中的onSubmit触发器并将其放在SignIn.js中来解决了这一问题。我将按钮的类型也更改为键入按钮。可以用了:)