我已经按照一些教程在React,Node和Redux中构建了一个身份验证。但是,当我保持应用程序打开然后返回它(当会话过期时)时,基本功能有效,我收到以下错误消息:
Unhandled Rejection (TypeError): Cannot read property 'uploadURL' of undefined
然后我刷新页面,我收到此错误消息:
TypeError: Cannot read property 'push' of undefined
然后,我再次刷新页面,最后我在主页上重定向。前两个错误是一个问题,我不知道如何摆脱它们。
这就是我的代码:
class Event extends Component {
constructor() {
super();
...
}
UNSAFE_componentWillMount() {
// I thought this if-block will redirect the user if the session is expired
if(!this.props.auth.isAuthenticated) {
console.log('unauthorized');
this.props.history.push('/');
}
this.uppy2 = new Uppy({ id: 'uppy2', autoProceed: true, debug: true })
.use(Tus, { endpoint: 'https://master.tus.io/files/' })
.on('complete', (result) => {
console.log(`Upload complete! We’ve uploaded these files: ${result.successful[0].uploadURL}`);
});
}
...
}
Event.propTypes = {
registerUser: PropTypes.func.isRequired,
auth: PropTypes.object.isRequired,
errors: PropTypes.object.isRequired
};
const mapStateToProps = state => ({
auth: state.auth,
errors: state.errors
});
export default connect(mapStateToProps,{ registerUser })(withRouter(Event))
这是Redux代码(我是MERN堆栈的初学者):
import axios from 'axios';
import { GET_ERRORS, SET_CURRENT_USER } from './types'; // we list here the actions we'll use
import setAuthToken from '../../setAuthToken';
import jwt_decode from 'jwt-decode';
export const registerUser = (user, history) => dispatch => {
axios.post('/api/users/register', user)
.then(res => history.push('/login'))
.catch(err => {
dispatch({
type: GET_ERRORS,
payload: err.response.data
});
});
}
export const loginUser = (user) => dispatch => {
axios.post('/api/users/login', user)
.then(res => {
//console.log(res.data);
const { token } = res.data;
localStorage.setItem('jwtToken', token);
setAuthToken(token);
const decoded = jwt_decode(token);
dispatch(setCurrentUser(decoded));
})
.catch(err => {
dispatch({
type: GET_ERRORS,
payload: err.response.data
});
});
}
export const setCurrentUser = decoded => {
return {
type: SET_CURRENT_USER,
payload: decoded
}
}
export const logoutUser = (history) => dispatch => {
localStorage.removeItem('jwtToken');
setAuthToken(false);
dispatch(setCurrentUser({}));
history.push('/login');
}
如何防止会话过期时发生的错误?
先感谢您!
如果在会话到期之前加载页面,则不会调用ComponentWillMount。我怀疑第一个错误是由一些丢失的数据引起的,因为带有过期令牌的请求失败了。您需要确保处理401或403错误并清除Redux状态,以便在发生这种情况时显示登录页面。
我不确定这部分!this.props.auth.isAuthenticated
。你使用mapDispatchToProps
和connect
用于还原吗?您需要在Event类中执行此操作以访问reducer。
你可以做的事情是,在渲染你的jsx代码之前,声明一个像let redirect = null
这样的变量,如果!this.props.auth.isAuthenticated
是正确的,把这个重定向变量设置为redirect = <Redirect to="/" />
(如果你使用浏览器路由!)并像这样使用这个变量,
render() {
return (
{redirect}
)
}