Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/405.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用Typescript通过getInitialProps将prop传递到Next.js中的每个页面_Javascript_Reactjs_Typescript_Next.js - Fatal编程技术网

Javascript 使用Typescript通过getInitialProps将prop传递到Next.js中的每个页面

Javascript 使用Typescript通过getInitialProps将prop传递到Next.js中的每个页面,javascript,reactjs,typescript,next.js,Javascript,Reactjs,Typescript,Next.js,我有一个例子,在页面呈现到服务器端并使用Next.js发送回我之前,我需要知道用户是否登录,以避免UI中出现闪烁变化 如果用户已经使用这个HOC组件登录,我就能够找出如何阻止他访问某些页面 export const noAuthenticatedAllowed = (WrappedComponent: NextPage) => { const Wrapper = (props: any) => { return <WrappedComponent {..

我有一个例子,在页面呈现到服务器端并使用Next.js发送回我之前,我需要知道用户是否登录,以避免UI中出现闪烁变化

如果用户已经使用这个HOC组件登录,我就能够找出如何阻止他访问某些页面

export const noAuthenticatedAllowed = (WrappedComponent: NextPage) => {
    const Wrapper = (props: any) => {
        return <WrappedComponent {...props} />;
    };

    Wrapper.getInitialProps = async (ctx: NextPageContext) => {
        let context = {};
        const { AppToken } = nextCookie(ctx);
        if (AppToken) {
            const decodedToken: MetadataObj = jwt_decode(AppToken);
            const isExpired = () => {
                if (decodedToken.exp < Date.now() / 1000) {
                    return true;
                } else {
                    return false;
                }
            };

            if (ctx.req) {
                if (!isExpired()) {
                    ctx.res && ctx.res.writeHead(302, { Location: "/" });
                    ctx.res && ctx.res.end();
                }
            }

            if (!isExpired()) {
                context = { ...ctx };
                Router.push("/");
            }
        }

        const componentProps =
            WrappedComponent.getInitialProps &&
            (await WrappedComponent.getInitialProps(ctx));

        return { ...componentProps, context };
    };

    return Wrapper;
};
然而,为了将prop
userAuthenticated
传递给我拥有的全局布局,我不得不用这个HOC包装每个页面,因为我不能用它包装“_app.tsx”类组件,它总是给我一个错误

这很有效

export default isAuthenticated(Home);
export default isAuthenticated(about);
但这不

export default withRedux(configureStore)(isAuthenticated(MyApp));
因此,必须对每个页面执行此操作,然后将道具传递到每个页面的全局布局,而不是仅在“_app.tsx”中执行一次,这有点烦人

我猜原因可能是因为“_app.tsx”是一个类组件,而不是像其他页面一样的函数组件? 我不知道,我只是在猜测


有什么帮助吗?

对于那些可能遇到相同问题的人,我可以通过以下方式解决这个问题

import React from "react";
import App from "next/app";
import { Store } from "redux";
import { Provider } from "react-redux";
import withRedux from "next-redux-wrapper";
import { ThemeProvider } from "styled-components";
import GlobalLayout from "../components/layout/GlobalLayout";
import { configureStore } from "../store/configureStore";
import { GlobalStyle } from "../styles/global";
import { ToastifyStyle } from "../styles/toastify";
import nextCookie from "next-cookies";
import jwt_decode from "jwt-decode";

 export interface MetadataObj {
   [key: string]: any;
 }

const theme = {
    color1: "#00CC99",
    color2: "#CC0000"
};

export type ThemeType = typeof theme;

interface Iprops {
    store: Store;
    userAuthenticated: boolean;
}

class MyApp extends App<Iprops> {
    // Only uncomment this method if you have blocking data requirements for
    // every single page in your application. This disables the ability to
    // perform automatic static optimization, causing every page in your app to
    // be server-side rendered.

    static async getInitialProps({ Component, ctx }: any) {
        let userAuthenticated = false;

        const { AppToken } = nextCookie(ctx);
        if (AppToken) {
            const decodedToken: MetadataObj = jwt_decode(AppToken);
            const isExpired = () => {
                if (decodedToken.exp < Date.now() / 1000) {
                    return true;
                } else {
                    return false;
                }
            };

            if (ctx.isServer) {
                if (!isExpired()) {
                    userAuthenticated = true;
                }
            }

            if (!isExpired()) {
                userAuthenticated = true;
            }
        }

        return {
            pageProps: Component.getInitialProps
                ? await Component.getInitialProps(ctx)
                : {},
            userAuthenticated: userAuthenticated
        };
    }

    render() {
        const { Component, pageProps, store, userAuthenticated } = this.props;
        return (
            <Provider store={store}>
                <ThemeProvider theme={theme}>
                    <>
                        <GlobalStyle />
                        <ToastifyStyle />
                        <GlobalLayout userAuthenticated={userAuthenticated}>
                            <Component {...pageProps} />
                        </GlobalLayout>
                    </>
                </ThemeProvider>
            </Provider>
        );
    }
}

export default withRedux(configureStore)(MyApp);
从“React”导入React;
从“下一个/应用程序”导入应用程序;
从“redux”导入{Store};
从“react redux”导入{Provider};
从“下一个redux包装器”导入withRedux;
从“样式化组件”导入{ThemeProvider};
从“./components/layout/GlobalLayout”导入GlobalLayout;
从“./store/configureStore”导入{configureStore};
从“./styles/global”导入{GlobalStyle};
从“./styles/toastify”导入{ToastifyStyle};
从“下一个Cookie”导入下一个Cookie;
从“jwt解码”导入jwt_解码;
导出接口MetadataObj{
[键:字符串]:任意;
}
常量主题={
颜色1:#00CC99“,
颜色2:#CC0000”
};
导出类型ThemeType=主题的类型;
接口Iprops{
商店:商店;
userAuthenticated:boolean;
}
类MyApp扩展了应用程序{
//仅当您对有阻塞数据要求时,才取消对该方法的注释
//应用程序中的每个页面。这将禁用
//执行自动静态优化,使应用程序中的每个页面
//可以在服务器端呈现。
静态异步getInitialProps({Component,ctx}:any){
让userAuthenticated=false;
const{AppToken}=nextCookie(ctx);
if(AppToken){
const decodedToken:MetadataObj=jwt_decode(AppToken);
常量isExpired=()=>{
if(decodedToken.exp
正如您所见,我发布了整个_app.tsx组件,以便您可以看到我使用的软件包

我正在用Typescript使用
nextredux包装器
样式化组件

我必须将
gitsinitialprops
中的
appContext
作为类型
any
,否则它将无法工作。因此,如果您有更好的
类型
建议,请告诉我。我尝试使用类型
NextPageContext
,但由于某种原因,在本例中,该类型不起作用


有了这个解决方案,我能够知道用户是否进行了身份验证,并将一个道具传递给全局布局,这样我就可以在每页中使用它,而不必每页都这样做,如果你不希望页眉和页脚每次都被呈现,那么如果它们必须依赖
userAuthenticated
prop,因为现在你只需将页眉和页脚放在
GlobalLayout
组件中,仍然可以使用
userAuthenticated
道具:D

我的评论与你的帖子和答案无关。我想说,
ReactJS
遵循函数式编程和面向对象编程,但我在你的代码中看到了后端开发的思维方式和面向对象的思想。从另一个组件继承一个新类@我明白你的意思,我什么都试过了。问题在于SSR,如果我使用“CreateReact应用程序”并进行“客户端渲染”,我根本不会这样做,但我无法让它以任何其他方式使用SSR,它甚至是Next.js推荐的方式。
import React from "react";
import App from "next/app";
import { Store } from "redux";
import { Provider } from "react-redux";
import withRedux from "next-redux-wrapper";
import { ThemeProvider } from "styled-components";
import GlobalLayout from "../components/layout/GlobalLayout";
import { configureStore } from "../store/configureStore";
import { GlobalStyle } from "../styles/global";
import { ToastifyStyle } from "../styles/toastify";
import nextCookie from "next-cookies";
import jwt_decode from "jwt-decode";

 export interface MetadataObj {
   [key: string]: any;
 }

const theme = {
    color1: "#00CC99",
    color2: "#CC0000"
};

export type ThemeType = typeof theme;

interface Iprops {
    store: Store;
    userAuthenticated: boolean;
}

class MyApp extends App<Iprops> {
    // Only uncomment this method if you have blocking data requirements for
    // every single page in your application. This disables the ability to
    // perform automatic static optimization, causing every page in your app to
    // be server-side rendered.

    static async getInitialProps({ Component, ctx }: any) {
        let userAuthenticated = false;

        const { AppToken } = nextCookie(ctx);
        if (AppToken) {
            const decodedToken: MetadataObj = jwt_decode(AppToken);
            const isExpired = () => {
                if (decodedToken.exp < Date.now() / 1000) {
                    return true;
                } else {
                    return false;
                }
            };

            if (ctx.isServer) {
                if (!isExpired()) {
                    userAuthenticated = true;
                }
            }

            if (!isExpired()) {
                userAuthenticated = true;
            }
        }

        return {
            pageProps: Component.getInitialProps
                ? await Component.getInitialProps(ctx)
                : {},
            userAuthenticated: userAuthenticated
        };
    }

    render() {
        const { Component, pageProps, store, userAuthenticated } = this.props;
        return (
            <Provider store={store}>
                <ThemeProvider theme={theme}>
                    <>
                        <GlobalStyle />
                        <ToastifyStyle />
                        <GlobalLayout userAuthenticated={userAuthenticated}>
                            <Component {...pageProps} />
                        </GlobalLayout>
                    </>
                </ThemeProvider>
            </Provider>
        );
    }
}

export default withRedux(configureStore)(MyApp);