反应无效的钩子调用。挂钩只能在功能组件的主体内部调用

时间:2020-08-17 16:18:45

标签: reactjs axios

我是新手,现在正在尝试解决此错误。基本上,我正在基于axios创建一个HttpAuthClient,并希望向每个请求添加访问令牌。当我尝试单击该按钮时,我收到一个错误-“未处理的拒绝(错误):无效的挂钩调用。挂钩只能是称为功能组件内部”。

组件

import React, { useState } from 'react';
import { HttpAuthClient } from "../HttpAuthClient/HttpAuthClient";

export const Content = () => {

    const [pages, setPages] = useState(null);
    const apiUrl = "https://xxxxx/";
           
    const loadPages = async () => {
        const response = await HttpAuthClient.get(apiUrl); //Error thrown
        setPages(response.data);
        console.log(pages);

    };
    
    return (
        <button onClick={loadPages}>Load Pages</button>
    )
};

HttpAuthClient

import Axios, { AxiosRequestConfig } from 'axios';
import { useAuthContext } from '../AuthContext/AuthContext';

const RequestHandler = (request: AxiosRequestConfig) => {
    const { accessToken, isAuthenticated } = useAuthContext(); //Error thrown

    if (isAuthenticated) {
        request.headers['Authorization'] = `Bearer ${accessToken}`;
    }

    return request;
};

const HttpAuthClient = Axios.create();

HttpAuthClient.interceptors.request.use((request: AxiosRequestConfig) =>
    RequestHandler(request)
);

export default HttpAuthClient;

AuthContext

import { createContext, useContext } from 'react';
import { IAuthContext } from '../../types/IAuthContext';

export const AuthContext = createContext<IAuthContext>({
    user: null,
    isAuthenticated: null,
    accessToken: ''
});

export const useAuthContext = () => useContext(AuthContext);

AuthProvider

import React, { useState, useEffect } from 'react';
import { useOktaAuth } from '@okta/okta-react';
import { AuthContext } from '../../components/AuthContext/AuthContext';
import { IAuthContext } from '../../types/IAuthContext';
import { IUserInfo } from '../../types/IUserInfo';

const AuthProvider = (props: any) => {
    const { authState, authService } = useOktaAuth();
    const [authContext, setAuthContext] = useState<IAuthContext>(
        {} as IAuthContext
    );

    useEffect(() => {
        if (!authState.isAuthenticated) {
            setAuthContext({} as IAuthContext);
        } else {
            authService.getUser().then((info: IUserInfo) => {
                setAuthContext({
                    accessToken: authState.accessToken,
                    isAuthenticated: authState.isAuthenticated,
                    user: info
                });
            });
        }
    }, [authState, authService]);

    return (
        <AuthContext.Provider value={authContext}>
            {props.children}
        </AuthContext.Provider>
    );
};

export default AuthProvider;

反应Stacktrace

react-dom.development.js:14724 Uncaught (in promise) Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
See fb.me/react-invalid-hook-call for tips about how to debug and fix this problem.
    at Object.throwInvalidHookError (react-dom.development.js:14724)
    at useContext (react.development.js:1493)
    at useAuthContext (AuthContext.tsx:10)
    at RequestHandler (HttpAuthClient.tsx:5)
    at HttpAuthClient.tsx:16
    at async loadPages (Content.tsx:10)

1 个答案:

答案 0 :(得分:0)

如错误所述

"Unhandled Rejection (Error): Invalid hook call. Hooks can only be called inside of the body of a function component"

您不能在组件外部使用钩子,并且您的RequestHandler不是组件, 您需要找到另一种方式来像Redux商店一样为您提供令牌。

您还可以像cookie或本地存储/会话存储一样进行Web存储,但这可能是安全漏洞Is it safe to store a jwt in localStorage with reactjs?