Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript react-redux:无法读取属性';isLogin';未定义的_Javascript_Reactjs_React Redux - Fatal编程技术网

Javascript react-redux:无法读取属性';isLogin';未定义的

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

我使用JWT令牌身份验证进行身份验证

当我使用令牌访问
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文件并导入它怎么样?