Javascript ReactJs,Typescript保护路由,以HOC作为功能组件
我不知道如何构建一个简单的HOC来保护组件,也就是说,在组件呈现之前,确保用户已登录 下面是我构建HOC以保护组件的尝试(目前还不起作用)Javascript ReactJs,Typescript保护路由,以HOC作为功能组件,javascript,reactjs,next.js,Javascript,Reactjs,Next.js,我不知道如何构建一个简单的HOC来保护组件,也就是说,在组件呈现之前,确保用户已登录 下面是我构建HOC以保护组件的尝试(目前还不起作用) 导出默认函数ProtectedRoute(组件:React.ComponentType){ return()=>{ const authUser=useSession(); const router=useRouter(); 如果(窗口类型===‘未定义’){ 返回null; } 如果(!authUser){ router.push('/login'); 返
导出默认函数ProtectedRoute(组件:React.ComponentType){
return()=>{
const authUser=useSession();
const router=useRouter();
如果(窗口类型===‘未定义’){
返回null;
}
如果(!authUser){
router.push('/login');
返回null;
}
返回;
};
}
这是我想要保护的组件
const AppLayout=({
儿童
标题='这是默认标题',
}:道具):React.ReactElement=>{
返回(
...
{儿童}
)
}
导出默认的ProtectedRoute(AppLayout);
这是我如何调用布局组件的:
函数应用程序({Component,pageProps}:any){
返回(
)
}
导出默认应用程序;
这是我的错误消息:类型为“({children,title,}:Props)=>React.ReactElement”的参数不能分配给类型为“ComponentType”的参数。类型“({children,title,}:Props)=>React.ReactElement”不可分配给类型“FunctionComponent”。参数“\u0”和“props”的类型不兼容。类型“{children?:ReactNode;}”中缺少属性“title”,但类型“Props”中需要属性“title”
您有什么提示吗?简而言之,您的
AppLayout
不会返回ReactElement
,而是返回FC
(功能组件)
我建议这种类型的差异
下面是一个可以找到的工作示例项目 组件/AppContext/index.tsx
import { createContext, useCallback, useContext, useState } from "react";
import type { FC, ReactNode } from "react";
type Context = {
isAuthenticated: Boolean;
handleAuthentication: () => void;
}
const AppContext = createContext<Context>({
isAuthenticated: false,
handleAuthentication: () => {},
});
const AppContextProvider: FC<{ children: ReactNode }> = ({ children }) => {
const [isAuthenticated, setAuthentication] = useState(false);
const handleAuthentication = useCallback(() => {
setAuthentication((prevState) => !prevState);
}, []);
return (
<AppContext.Provider
value={{
isAuthenticated,
handleAuthentication,
}}
>
{children}
{isAuthenticated && (
<button type="button" onClick={handleAuthentication}>
Log out
</button>
)}
</AppContext.Provider>
);
};
export const useAppContext = () => useContext(AppContext);
export default AppContextProvider;
import { useRouter } from "next/router";
import { useEffect } from "react";
import { useAppContext } from "../AppContext";
import type { FC } from "react";
type withAuthenticationFn = (Component: FC) => FC;
const withAuthentication: withAuthenticationFn = (Component) => {
const Authenticated: FC = (): JSX.Element | null => {
const { isAuthenticated } = useAppContext();
const router = useRouter();
useEffect(() => {
if (!isAuthenticated) router.push("/login");
});
return isAuthenticated ? <Component /> : null;
};
return Authenticated;
};
export default withAuthentication;
import AppContextProvider from "../components/AppContext";
import type { FC } from "react";
import type { AppProps } from "next/app";
const App: FC<AppProps> = ({ Component, pageProps }) => (
<AppContextProvider>
<Component {...pageProps} />
</AppContextProvider>
);
export default App;
import Head from "next/head";
import Link from "next/link";
import withAuthentication from "../components/withAuthentication";
import type { NextPage } from "next";
const AboutPage: NextPage = () => (
<>
<Head>
<title> About - Next App</title>
</Head>
<h1>About</h1>
<p>This is the about page</p>
<p>
<Link href="/">
<a>Go home</a>
</Link>
</p>
</>
);
export default withAuthentication(AboutPage);
从“react”导入{createContext,useCallback,useContext,useState};
从“react”导入类型{FC,ReactNode};
类型上下文={
未验证:布尔值;
手工验证:()=>无效;
}
const AppContext=createContext({
I认证:错误,
handleAuthentication:()=>{},
});
常量AppContextProvider:FC=({children})=>{
const[isAuthenticated,setAuthentication]=useState(false);
const handleAuthentication=useCallback(()=>{
setAuthentication((prevState)=>!prevState);
}, []);
返回(
);
使用身份验证导出默认值(约页);
页面/索引.tsx
import { createContext, useCallback, useContext, useState } from "react";
import type { FC, ReactNode } from "react";
type Context = {
isAuthenticated: Boolean;
handleAuthentication: () => void;
}
const AppContext = createContext<Context>({
isAuthenticated: false,
handleAuthentication: () => {},
});
const AppContextProvider: FC<{ children: ReactNode }> = ({ children }) => {
const [isAuthenticated, setAuthentication] = useState(false);
const handleAuthentication = useCallback(() => {
setAuthentication((prevState) => !prevState);
}, []);
return (
<AppContext.Provider
value={{
isAuthenticated,
handleAuthentication,
}}
>
{children}
{isAuthenticated && (
<button type="button" onClick={handleAuthentication}>
Log out
</button>
)}
</AppContext.Provider>
);
};
export const useAppContext = () => useContext(AppContext);
export default AppContextProvider;
import { useRouter } from "next/router";
import { useEffect } from "react";
import { useAppContext } from "../AppContext";
import type { FC } from "react";
type withAuthenticationFn = (Component: FC) => FC;
const withAuthentication: withAuthenticationFn = (Component) => {
const Authenticated: FC = (): JSX.Element | null => {
const { isAuthenticated } = useAppContext();
const router = useRouter();
useEffect(() => {
if (!isAuthenticated) router.push("/login");
});
return isAuthenticated ? <Component /> : null;
};
return Authenticated;
};
export default withAuthentication;
import AppContextProvider from "../components/AppContext";
import type { FC } from "react";
import type { AppProps } from "next/app";
const App: FC<AppProps> = ({ Component, pageProps }) => (
<AppContextProvider>
<Component {...pageProps} />
</AppContextProvider>
);
export default App;
import Head from "next/head";
import Link from "next/link";
import withAuthentication from "../components/withAuthentication";
import type { NextPage } from "next";
const AboutPage: NextPage = () => (
<>
<Head>
<title> About - Next App</title>
</Head>
<h1>About</h1>
<p>This is the about page</p>
<p>
<Link href="/">
<a>Go home</a>
</Link>
</p>
</>
);
export default withAuthentication(AboutPage);
从“下一个/链接”导入链接;
从“下一个/Head”导入Head;
从“./components/withAuthentication”导入withAuthentication;
从“下一步”导入类型{NextPage};
常量索引扩展:下一页=()=>(
仪表板-下一个应用程序
你好,Next.js