在逻辑之前使用异步调用渲染组件来响应HOC

时间:2019-03-05 13:49:29

标签: javascript reactjs axios

我只想在拥有令牌且此令牌有效时才渲染组件。要检查令牌是否有效,我必须向API发送POST请求。我是在componentWillMount内部完成的。我还尝试将其放在componentDidMount中,但始终总是先呈现重定向,然后呈现导致控制台中此错误的组件:Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in the componentWillUnmount method in Authenticate (created by Route).我只是想呈现组件,如果authenticated: true,否则重定向到登录路径。

authCheck.js

export default (ComposedComponent) =>
    class Authenticate extends Component {

        state = {
            authenticated: false,
        };

        componentWillMount() {
            this.checkAndRedirect();
        }

        checkAndRedirect() {
            const token = localStorage.getItem('token') || null;
            const config = {
                headers: {"Authorization": `Bearer ${token}`}
            };
            if (token) {
                axios.post(
                    'https://alessandroarcidiaco.it/wp-json/jwt-auth/v1/token/validate',
                    null,
                    config
                )
                    .then(res => {
                        if (res.status === 200) {
                            this.setState({authenticated: true})
                        }
                    })
                    .catch(err => {
                        this.setState({authenticated: false})
                    })
            } else {
                this.setState({authenticated: false});
            }
        }

        render() {
            if (this.state.authenticated){
                return <ComposedComponent />
            }
            return <Redirect to="/login" />
        }
    }

2 个答案:

答案 0 :(得分:3)

它接缝的是,当render()方法第一次运行时,您的“ this.state.authenticated”为“ false”,因此您将重定向到“ / login”。

发布请求返回并且“ this.state.authenticated”设置为“ true”时,您将已经是“ / login”屏幕。

您可以修复将“已验证”初始化为“未定义”的问题

state = {
    authenticated: undefined,
};

并且只有在它为“ false”时才重定向

render() {
    if (this.state.authenticated){
        return <ComposedComponent />
    } else if ( this.state.authenticated === false) { //pay attention on '===', it is not '=='
        return <Redirect to="/login" />
    } else {
        <p>Loading...</p>
    }
}

答案 1 :(得分:3)

您正在使用componentWillMount,这是一种不安全不推荐使用的方法,并且在应避免出现副作用的情况下 。 (来自React Doc

正如错误所述,您正在更新未安装组件的状态:checkAndRedirect在安装组件之前会触发setState,因为它已在componentWillMount中被调用。

您必须使用componentDidMount来执行这些操作并重新考虑您的代码,因为正如您所说的,您将始终陷入<Redirect to="/login" />中。在authenticated初始化undefined并在渲染器中的true/false上播放即可完成这项工作。