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:1411 | 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} >
。
因此,在搜索了几个小时之后,我终于能够找到上述问题的解决方案。
回顾一下,我使用了react-router-dom来处理应用程序中从SignIn组件到My Dashboard的路由。我向所有其他路由组件添加了HOC,希望SignIn组件检查用户是否已通过身份验证;如果不是,则将用户路由回SignIn组件。
问题如下:
解决方案:
- 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服务器进行查询,并处理数据,错误