关于javascript:在React Component上使用package函数通过浏览器路由器对用户登录进行身份验证时,如何解决” TypeError:Object(…)不是一个函数”

How to fix “TypeError: Object(…) is not a function” when using a wrap function on React Component to authenticate user login with Browser Router

我正在构建一个React应用程序,并在进行用户身份验证。
目前,我正在使用" react-router-dom"中的BrowserRouter来管理应用程序中的路由。
我有一个注册路由,所有其他路由组件都package在一个函数" withAuth"中。
" withAuth"的作用是查看应用程序是否对使用进行了身份验证。如果用户通过了身份验证,则应加载该组件(在此处出现问题!),否则应将其重定向到登录组件(工作正常!)。

登录后,当应用程序重定向到" withAuth"函数中将组件package在其中的路径时。我收到以下错误:

TypeError: Object(...) is not a function
(anonymous function)
F:/Projects/beyouplus/beyouplus/beyouplus-client/src/services/auth.service.js:14

11 | return useContext(MyContext)

12 | }

13 |

>14 | export const withAuth = (Component) => (props) => {

15 | if (!isSignedIn()) {

16 | if (props.history.location.pathname === '/sign-in') {

17 | return null

我的App.js:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import React from 'react';
import {
  BrowserRouter,
  Route,
  Redirect
} from 'react-router-dom'

// Import Screens
import SignInScreen from './components/SignInScreen'
import DepartmentScreen from './components/DepartmentScreen'

// Import Services
import { withAuth } from './services/auth.service'

const App = () => (
  <BrowserRouter>
    <Route exact path="/sign-in" component={SignInScreen}/>
    <Route exact path="/dept" component={withAuth(DepartmentScreen)}/>
    <Route exact path="/" render={redirectToDept} />
  </BrowserRouter>
)

const redirectToDept = () => (
  <Redirect to="/dept" />
)

export default App;

auth.service.js文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
import React, { useContext } from 'react'
import { Redirect } from 'react-router-dom'

import client from '../client'
import { getMeQuery } from '../graphql/queries'
import { useCacheService } from './cache.service'

const MyContext = React.createContext(null)

export const useMe = () => {
    return useContext(MyContext)
}

export const withAuth = (Component) => (props) => {
    if (!isSignedIn()) {
        if (props.history.location.pathname === '/sign-in') {
            return null
        }

        return (
            <Redirect to="/sign-in" />
        )
    }

    const { data, error, loading } = getMeQuery()

    useCacheService()

    if(loading) return null

    if(error || !data.me) {
        signOut()

        return <Redirect to="/sign-in" />
    }

    console.log(data.me)

    return (
        <MyContext.Provider value={data.me}>
            <Component {...props} />
        </MyContext.Provider>
    )
}

export const isSignedIn = () => {
    //return /authToken=.+(;!$)/.test(document.cookie)
    return document.cookie.includes('authToken')
}

编辑:
我发现问题出在withAuth HOC声明的语法上,我用以下内容对其进行了更新,并且可以正常加载。除了现在,当我使用" componentDidMount"进行graphql查询时,HOC并未运行" componentDidMount"。
auth.service.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
export const withAuth = (Component) => {
    return class extends React.Component {

        state = {
            data: null
        }

        componentDidMount() {
            if (!isSignedIn()) {
                if (this.props.history.location.pathname === '/sign-in') {
                    return null;
                }
                return (
                    <Redirect to="/sign-in" />
                );
            }

            const { data, error, loading } = getMeQuery;

            useCacheService();

            if (loading) return null;
            if (data === undefined) return null;

            if (error || !data.me) {
                signOut();
                return <Redirect to="/sign-in" />;
            }

            this.setState({
                data
            })
        }

        render() {      
            const { data } = this.state;

            return (
                <MyContext.Provider value={data.me}>
                    <Component {...this.props} />
                </MyContext.Provider>
            )
        }
    }
}

所以我得到了错误

TypeError: Cannot read property 'me' of null

/> 52 | < MyContext.Provider value={data.me} >

HOC中的render()中的


因此,在搜索了几个小时之后,我终于能够找到上述问题的解决方案。

回顾一下,我使用了react-router-dom来处理应用程序中从SignIn组件到My Dashboard的路由。我向所有其他路由组件添加了HOC,希望SignIn组件检查用户是否已通过身份验证;如果不是,则将用户路由回SignIn组件。

问题如下:

  • 我在我的HOC内收到TypeError:Object(...)不是一个函数,以验证登录用户。
  • 在HOC中时,我无法进行graphql查询并获取当前用户的data.me。
  • 解决方案:

    • HOC TypeError:我的语法错误,我没有返回组件!

    A higher-order component is a function that takes a component and returns a new component.

    • 要获取data.me:

    • 要使用apollo进行graphql查询,需要访问客户端。

    • 我必须确保我是从根目录通过" react-apollo"传递来自" ApolloProvider"的客户端的。

    • 比起使用来自'react-apollo'的查询来对graphql服务器进行查询,并处理数据,错误