[英]UseEffect not fired when redux props change caused by async api call with redux-thunk
I have a functional login page connected with redux, I'm firing an async event onSubmit that will trigger the emailLogin
action, I am using useEffect
to detect the change of the isLoading
prop to see whether login finished or not.我有一个与 redux 连接的功能登录页面,我正在触发一个异步事件 onSubmit 将触发
emailLogin
操作,我正在使用useEffect
来检测isLoading
道具的更改以查看登录是否完成。 If login success, the redux store should have the user object, if failed, the user should remain null.如果登录成功,redux store 应该有 user 对象,如果登录失败,user 应该保持为 null。
The question is, I know that the login is success, which should triggered the change of isLoading
, the parameter that decide whether the useEffect
, however, the useEffect
is not fired.问题是,我知道登录成功,应该触发
isLoading
的更改,决定是否使用useEffect
的参数,但是, useEffect
没有被触发。 Also, the console.log('done');
另外,
console.log('done');
after the line await emailLogin(authData);
在
await emailLogin(authData);
is never fired.永远不会被解雇。 Ssomething is wrong.
有什么不对。
import React, { useState, useEffect } from 'react';
import { connect } from 'react-redux';
import { Link, useHistory } from 'react-router-dom';
import { emailLogin } from '../actions/index';
function Login({ user, isLoading, emailLogin }) {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const history = useHistory();
useEffect(() => {
console.log('useEffect fired', user, isLoading); //<-----This does not fire after login success
if (user) {
history.push('/protected_home');
}
}, [isLoading]);
const submitEmailLoginForm = async (e) => {
e.preventDefault();
const authData = { email, password };
await emailLogin(authData);
console.log('done'); // <------- This is never fired
};
return (
<div>
<h2>Login</h2>
<Link to="/">back</Link>
<form onSubmit={submitEmailLoginForm}>
<label>
email:
<input
type="text"
name="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
</label>
<label>
password:
<input
type="text"
name="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
/>
</label>
<input type="submit" value="Submit" />
</form>
</div>
);
}
const mapStateToProps = (state) => ({
user: state.user,
isLoading: state.isLoading
});
const mapDispatch = {
emailLogin: emailLogin
};
export default connect(mapStateToProps, mapDispatch)(Login);
My action file:我的操作文件:
import axios from 'axios';
export const authActions = {
EMAIL_LOGIN_START: '@@EMAIL_LOGIN_START',
EMAIL_LOGIN_SUCCESS: '@@EMAIL_LOGIN_SUCCESS'
};
export const emailLogin = ({ email, password }) => async (dispatch) => {
dispatch({ type: authActions.EMAIL_LOGIN_START });
try {
const response = await axios.post('http://localhost:5001/api/auth', {
email: email,
password: password
});
dispatch({
type: authActions.EMAIL_LOGIN_SUCCESS,
payload: {
user: { ...response.data }
}
});
} catch (error) {
console.log('Should dispatch api error', error.response);
}
};
My Reducer:我的减速机:
import { authActions } from '../actions/index';
const initialState = {
user: null,
isLoading: false
};
const userReducer = (state = initialState, action) => {
switch (action.type) {
case authActions.EMAIL_LOGIN_START:
return { ...state, isLoading: true };
case authActions.EMAIL_LOGIN_SUCCESS:
console.log('Reducer check => Login is success'); //<-----this line is printed
return { ...state, user: action.payload.user, isLoading: false };
default:
return state;
}
};
export default userReducer;
In the reducer, I see that the success action is actually triggered by checking the console.log()
.在减速器中,我看到成功操作实际上是通过检查
console.log()
触发的。 Also in the redux dev tool, I can actually see that the login is success and the isLoading
prop has changed :同样在 redux 开发工具中,我实际上可以看到登录成功并且
isLoading
道具已更改:
This solve my problem这解决了我的问题
const mapStateToProps = (state) => ({
user: state.userReducer.user,
isLoading: state.userReducer.isLoading
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.