React.jsx:类型无效 - 需要一个字符串(对于内置组件)或一个类/函数(对于复合组件)但得到:未定义
Posted
技术标签:
【中文标题】React.jsx:类型无效 - 需要一个字符串(对于内置组件)或一个类/函数(对于复合组件)但得到:未定义【英文标题】:React.jsx: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: undefined 【发布时间】:2022-01-12 08:23:16 【问题描述】:我已经使用 Firebase v9 和 React-router-dom v6 中的 auth API 构建了一条私有路由来访问管理部分,当我登录它时将我重定向到管理页面,但页面是空白的,控制台会记录这个“ React.jsx:类型无效 - 需要一个字符串(对于内置组件)或一个类/函数(对于复合组件),但得到:未定义。" 并让我“在 PrivateRoute.jsx:7 检查你的代码。”。谢谢你的帮助 =)。
PrivateRoute.jsx
import React from 'react'
import Navigate from 'react-router-dom'
import auth from '../../Firebase'
function PrivateRoute(component: Component)
const user = auth.currentUser
return user ? <Component /> : <Navigate to='/login'/>
export default PrivateRoute
App.jsx(使用私有路由的地方)
import BrowserRouter, Route, Routes from 'react-router-dom';
import Admin from './Components/Admin/Admin'
function App()
return (
<BrowserRouter>
<div className="App">
<Routes>
<Route
path="/admin"
element=
<PrivateRoute>
<Admin />
</PrivateRoute>
/>
</Routes>
</div>
</BrowserRouter>
);
export default App;
我让你把 Firebase 文件和 AuthContext 弄清楚
Firebase.js
import initializeApp from 'firebase/app'
import serverTimestamp, getFirestore from 'firebase/firestore'
import getStorage from 'firebase/storage'
import getAuth from'firebase/auth'
const firebaseConfig = config
const app = initializeApp(firebaseConfig)
export const timestamp = serverTimestamp()
export const projectFirestore= getFirestore(app)
export const projectStorage= getStorage(app)
export const auth = getAuth(app)
export default app
AuthContext.jsx
import useContext, useState, useEffect, createContext from 'react'
import auth from '../../Firebase'
import createUserWithEmailAndPassword, signInWithEmailAndPassword, signOut, onAuthStateChanged from "firebase/auth";
const AuthContext = createContext()
export function useAuth()
return useContext(AuthContext)
export function AuthProvider(children)
const [currentUser, setCurrentUser] = useState()
const [loading, setLoading] = useState(true)
function register(email, password)
return createUserWithEmailAndPassword(auth, email, password)
function login(email, password)
return signInWithEmailAndPassword(auth, email, password)
function logout()
signOut(auth)
useEffect(() =>
const unsubscribe = onAuthStateChanged(auth ,(user) =>
setCurrentUser(user)
setLoading(false)
)
return unsubscribe
, [])
const value =
currentUser,
login,
register,
logout
return (
<AuthContext.Provider value=value>
!loading && children
</AuthContext.Provider>
)
【问题讨论】:
您能分享一下您是如何/在哪里使用这个PrivateRoute
组件以及它是如何呈现的吗? React-router-dom v6 有很多重大变化,其中之一是不再使用自定义路由组件。
是的,我阅读了文档,但很多东西我没有得到。我会将其添加到请求中。
【参考方案1】:
RRDv6 中的身份验证方式与 v5 相比发生了显着变化。自定义路由组件已不复存在,取而代之的是包装组件。
给定:
<BrowserRouter>
<div className="App">
<Routes>
<Route
path="/admin"
element=(
<PrivateRoute>
<Admin />
</PrivateRoute>
)
/>
</Routes>
</div>
</BrowserRouter>
PrivateRoute
包装器只需要渲染其 children
属性而不是 component
属性。
function PrivateRoute( children )
const user = auth.currentUser;
return user ? children : <Navigate to='/login' replace />;
然而,一个常见的模式是在 Outlet
组件中渲染,并包装嵌套的受保护路由。
例子:
import Navigate, Outlet from 'react-router-dom';
const PrivateWrapper = ()
const user = auth.currentUser;
return user ? <Outlet /> : <Navigate to='/login' replace />;
...
<BrowserRouter>
<div className="App">
<Routes>
<Route path="/admin" element=<PrivateWrapper /> >
<Route path="/admin" element=<Admin /> />
... other nested protected routes ...
</Route>
</Routes>
</div>
</BrowserRouter>
【讨论】:
非常感谢 =')。最后一个问题,您在 Navigate 中“替换”了什么? 据我了解,我的情况不需要插座。 @PazzeG 哦,它用于指示导航应该是重定向而不是普通的 PUSH 导航。回复:Outlet
,我只是说得很彻底。以上是关于React.jsx:类型无效 - 需要一个字符串(对于内置组件)或一个类/函数(对于复合组件)但得到:未定义的主要内容,如果未能解决你的问题,请参考以下文章
Eslint react/jsx-one-expression-per-line:允许变量和 JSX 字符串在同一行,但不允许元素