টাইপস্ক্রিপ্ট ব্যবহার করে getInitialProp সহ Next.js এর প্রতিটি পৃষ্ঠায় প্রপস পাস করুন


10

আমার একটি মামলা আছে যখন পৃষ্ঠাটি সার্ভার-সাইড রেন্ডার হওয়ার আগে ব্যবহারকারী লগ ইন হয়েছে কিনা তা আমার জানা দরকার এবং ইউআইতে ফ্লিকার পরিবর্তন এড়াতে Next.js ব্যবহার করে আমাকে আবার প্রেরণ করা হয়েছে।

আমি যদি এইচওসি উপাদানটি ইতিমধ্যে লগ ইন করে থাকে তবে ব্যবহারকারীকে কিছু পৃষ্ঠাগুলি অ্যাক্সেস করা থেকে কীভাবে রোধ করবেন তা আমি বুঝতে সক্ষম হয়েছি ...

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;
};

এবং এটি দুর্দান্ত কাজ করে।

এখন, আমি কীভাবে এটির চারপাশে মোড়ানোর জন্য একটি অনুরূপ এইচওসি উপাদান তৈরি করতে পারি যাক "_app.tsx" বলি যাতে টোকনটি পেয়ে প্রতিটি ব্যবহারকারীকে "ইউজারআউট্টিস্টিকেটেড" প্রপ পাস করতে পারি এবং এটি নির্ধারিত হয় কি না এবং এর ভিত্তিতে নির্ধারিত হয় সেই প্রস্তাবটি আমি সেই বিরক্তিকর ঝাঁকুনির প্রভাব ছাড়াই ব্যবহারকারীর কাছে সঠিক ইউআইটি দেখাতে পারি?

আমি আশা করি আপনি এটির সাথে আমাকে সহায়তা করতে পারেন, আমি উপরের এইচওসিটি যেভাবে তৈরি করেছি ঠিক সেভাবেই করার চেষ্টা করেছি, তবে আমি এটি করতে পারিনি, বিশেষত টাইপসক্রিপ্টটি তার অদ্ভুত ত্রুটিগুলির দ্বারা এটিকে আরও সহজ করে না :(


সম্পাদনা == ==========================================

আমি এই জাতীয় এইচওসি উপাদান তৈরি করতে সক্ষম হয়েছি এবং userAuthenticatedপ্রতিটি পৃষ্ঠার জন্য প্রোটি এইরকম দিয়ে দিতে পারি ...

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

    Wrapper.getInitialProps = async (ctx: NextPageContext) => {
        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.req) {
                if (!isExpired()) {
                    // ctx.res && ctx.res.writeHead(302, { Location: "/" });
                    // ctx.res && ctx.res.end();
                    userAuthenticated = true;
                }
            }

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

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

        return { ...componentProps, userAuthenticated };
    };

    return Wrapper;
};

তবে আমার কাছে থাকা এই userAuthenticatedবিশ্বব্যাপী বিন্যাসের প্রপমটি পাস করার জন্য আমাকে এই এইচওসি দিয়ে প্রতিটি পৃষ্ঠাগুলি মুড়ে রাখতে হয়েছিল, কারণ "_app.tsx" শ্রেণীর উপাদানটি এটি দিয়ে মোড়ানো করতে পারি না, এটি সর্বদা আমাকে একটি ত্রুটি দেয়। ..

এইটা কাজ করে ...

export default isAuthenticated(Home);
export default isAuthenticated(about);

কিন্তু এটি না ...

export default withRedux(configureStore)(isAuthenticated(MyApp));

সুতরাং প্রতিটি পৃষ্ঠায় এটি করা কিছুটা বিরক্তিকর, এবং তারপরে প্রতিটি পৃষ্ঠায় গ্লোবাল লেআউটে প্রপটি কেবল "_app.tsx" এ একবার না করে দিয়ে দিন।

আমি অনুমান করছি কারণটি হতে পারে কারণ "_app.tsx" একটি বর্গ উপাদান এবং অন্যান্য পৃষ্ঠাগুলির মতো কোনও ফাংশন উপাদান নয়? আমি জানি না, আমি কেবল অনুমান করছি।

কোন সাহায্য?

উত্তর:


5

আপনারা যারা একই সমস্যাটি দেখতে পাচ্ছেন, তাদের জন্য আমি নিম্নলিখিত হিসাবে এটি সমাধান করতে সক্ষম হয়েছি ...

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);

আপনি দেখতে পেলাম আমি পুরো _app.tsx উপাদানটি পোস্ট করেছি যাতে আপনি যে প্যাকেজগুলি ব্যবহার করছেন তা দেখতে পান।

আমি next-redux-wrapperএবং styled-componentsটাইপস্ক্রিপ্ট ব্যবহার করছি ।

আমি ছিল appContextমধ্যে gitInitialPropsধরণ যেমন anyঅন্যথায় এটি কাজ করবে না। সুতরাং আপনার যদি আরও ভাল typeপরামর্শ থাকে তবে দয়া করে আমাকে জানান। আমি প্রকারটি ব্যবহার করার চেষ্টা করেছি NextPageContext, তবে এটি কোনও কারণে এই ক্ষেত্রে কার্যকর হয়নি।

এবং সেই সমাধানের সাহায্যে আমি জানতে পেরেছিলাম যে ব্যবহারকারী সত্যায়িত হয়েছে কিনা এবং বৈশ্বিক বিন্যাসে একটি প্রপস পাস করে যাতে আমি প্রতিটি পৃষ্ঠায় এবং পৃষ্ঠায় প্রতিটি পৃষ্ঠা না করেই এটি ব্যবহার করতে পারি এবং এটি ক্ষেত্রেও উপকৃত হয় আপনি চাইছেন না যে শিরোনাম এবং পাদলেখগুলি প্রতিবার রেন্ডার করা উচিত যদি সেগুলি userAuthenticatedপ্রপের উপর নির্ভর করতে হয় তবে কারণ আপনি এখন কেবলমাত্র শিরোনাম এবং পাদচরণটিকে GlobalLayoutউপাদানটিতে রাখতে পারেন এবং userAuthenticatedপ্রপটিকে আপনার নিষ্পত্তি করতে পারেন: ডি


আমার মন্তব্য আপনার পোস্ট এবং আপনার উত্তর সম্পর্কিত নয়। আমি বলতে চাই, ReactJSফাংশনাল প্রোগ্রামিং বা ওওপি অনুসরণ করে, তবে আমি ওওপি চিন্তাভাবনার সাথে আপনার কোডটিতে ব্যাকএন্ড বিকাশের মানসিকতা দেখতে পাচ্ছি। অন্য উপাদান থেকে একটি নতুন বর্গ উত্তরাধিকার! আমি এর আগে দেখিনি।
আমেরেলিকাএ

1
@ আমেরেলিকা আপনি যা বলছেন আমি তা পেয়েছি, আমি কেবল সবকিছুই চেষ্টা করেছি। সমস্যাটি এসএসআরের সাথে, যদি আমি "ক্রিয়েটিভ অ্যাপ্লিকেশন" এর সাথে কাজ করি এবং "ক্লায়েন্ট-সাইড রেন্ডারিং" করি তবে আমি তা মোটেও করব না, তবে এসএসআর এর সাথে অন্য কোনওভাবে কাজ করতে পারি না, এটি এমনকি Next.js দ্বারা প্রস্তাবিত উপায়
রুবি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.