Javascript react-redux:无法读取属性';isLogin';未定义的
我使用JWT令牌身份验证进行身份验证 当我使用令牌访问Javascript react-redux:无法读取属性';isLogin';未定义的,javascript,reactjs,react-redux,Javascript,Reactjs,React Redux,我使用JWT令牌身份验证进行身份验证 当我使用令牌访问localhost:4000/api/refresh时,它会验证令牌是否过期,并返回状态代码为200的刷新令牌 中间件检测令牌是否有效并返回到200或401 后端是完美的工作。但是前端有一些错误 我使用redux进行全局状态管理 这是我的密码 [reducers.js] // Actions const LOGIN_TRUE = 'LOGIN_TRUE'; const LOGIN_FALSE = 'LOGIN_FALSE'; const CH
localhost:4000/api/refresh
时,它会验证令牌是否过期,并返回状态代码为200的刷新令牌
中间件检测令牌是否有效并返回到200或401
后端是完美的工作。但是前端有一些错误
我使用redux进行全局状态管理
这是我的密码
[reducers.js]
// Actions
const LOGIN_TRUE = 'LOGIN_TRUE';
const LOGIN_FALSE = 'LOGIN_FALSE';
const CHECK_TOKEN = 'CHECK_TOKEN';
const REFRESH_TOKEN = 'REFRESH_TOKEN';
// Action Creators
function loginTrue() {
return {
type: LOGIN_TRUE
}
}
function loginFalse() {
return {
type: LOGIN_FALSE
}
}
function checkToken() {
return {
type: CHECK_TOKEN
}
}
function refreshToken() {
return {
type: REFRESH_TOKEN
}
}
// Reducer
const initialState = {
isLogin: false
}
function reducer(state = initialState, action) {
switch(action.type) {
case LOGIN_TRUE:
return applyLoginTrue(state, action);
case LOGIN_FALSE:
return applyLoginFalse(state, action);
case CHECK_TOKEN:
return applyCheckToken(state, action);
case REFRESH_TOKEN:
return applyRefreshToken(state, action);
default:
return state;
}
}
// Reducer Functions
function applyLoginTrue(state) {
return {
...state,
isLogin: true
}
}
function applyLoginFalse(state) {
return {
...state,
isLogin: false
}
}
function applyCheckToken(state) {
const token = localStorage.getItem('token');
if(token !== null) {
return {
...state,
isLogin: true
}
} else {
return {
...state,
isLogin: false
}
}
}
function applyRefreshToken(state) {
console.log(state);
const token = localStorage.getItem('token');
if(token !== null) {
fetch("http://localhost:4000/api/refresh", {
method: "POST",
headers: {
'Authorization':`JWT ${token}`
}
})
.then(res => {
if(res.status === 200) {
return res.json();
} else {
console.log("applyRefreshToken() res.status is not 200");
}
})
.then(json => {
localStorage.clear();
localStorage.setItem('token', json.token);
return {
...state,
isLogin: true
}
})
} else {
console.log("applyRefreshToken() token is null");
return {
...state,
isLogin: false
}
}
}
// Export Action Creators
export const actionCreators = {
loginTrue,
loginFalse,
checkToken,
refreshToken
};
// Export Reducer
export default reducer;
在编写reducer.js之后,我制作了虚拟组件来测试它
componentDidMount() {
const { refreshToken } = this.props;
refreshToken();
}
render () {
const { isLogin } = this.props;
return (
<div className="wrap">
{ isLogin ? "Under Construction" : "Login please" }
</div>
)
}
export default connect(mapStateToProps, mapDispatchToProps)(index);
[mapDispatchToProps.js]
const mapStateToProps = (state) => {
const { isLogin } = state;
return {
isLogin
}
}
export default mapStateToProps;
import { bindActionCreators } from 'redux';
import { actionCreators } from './reducer';
const mapDispatchToProps = (dispatch) => {
return {
loginTrue: bindActionCreators(actionCreators.loginTrue, dispatch),
loginFalse: bindActionCreators(actionCreators.loginFalse, dispatch),
checkToken: bindActionCreators(actionCreators.checkToken, dispatch),
refreshToken: bindActionCreators(actionCreators.refreshToken, dispatch)
}
}
export default mapDispatchToProps;
applyRefreshToken
是异步的,因此返回undefined
因此,当您的reducer执行时:
case REFRESH_TOKEN:
return applyRefreshToken(state, action);
实际上,您将状态设置为undefined
,这最终会将this.props
设置为undefined,从而导致错误
运行异步逻辑并在收到响应后分派新状态,或者使用
thunk
/saga
/任何其他中间件,使您能够拥有异步操作创建者。您的mapStateToProps功能如何,你能把它添加到你的例子中吗?@AlenGenzić我把它添加到我的帖子中。导出默认连接(MapStateTops,mapDispatchToProps)(index)中的索引是什么代码>可能与您的问题无关,但不要使用还原程序中的本地存储,.@pritesh index是虚拟组件。是否有任何方法使其异步?与async/await语句类似,仅返回承诺是不够的,redux不处理异步请求。我个人喜欢使用发电机,但thunk可能更直观一些。好的,我会检查一下。但是,为全局函数制作js文件并导入它怎么样?