Mam przypadek, gdy muszę wiedzieć, czy użytkownik jest zalogowany, czy nie, zanim strona zostanie renderowana po stronie serwera i odesłana do mnie za pomocą Next.js, aby uniknąć migotania zmian w interfejsie użytkownika.
Byłem w stanie dowiedzieć się, jak uniemożliwić użytkownikowi dostęp do niektórych stron, jeśli jest on już zalogowany przy użyciu tego komponentu 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;
};
I to działa świetnie.
Teraz, jak mogę zbudować podobny komponent HOC, aby go owinąć, powiedzmy „_app.tsx”, aby móc przekazać propozycję „UserAuthentified” na każdej stronie, pobierając token i stwierdzając, czy wygasł, czy nie i na podstawie ten rekwizyt mogę pokazać użytkownikowi odpowiedni interfejs bez tego irytującego efektu migotania?
Mam nadzieję, że możesz mi w tym pomóc. Próbowałem to zrobić w ten sam sposób, w jaki zbudowałem powyższy HOC, ale nie mogłem tego zrobić, tym bardziej, że maszynopis nie ułatwia tego z powodu swoich dziwnych błędów :(
Edytuj == ==========================================
Byłem w stanie stworzyć taki komponent HOC i przekazać pro userAuthenticated
do każdej strony w ten sposób ...
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;
};
Jednak musiałem zawinąć każdą stronę za pomocą tego HOC, aby przekazać prop userAuthenticated
do globalnego układu, który posiadam, ponieważ nie mogłem go owinąć komponentem klasy „_app.tsx”, zawsze daje mi to błąd. ..
To działa ...
export default isAuthenticated(Home);
export default isAuthenticated(about);
Ale to nie ...
export default withRedux(configureStore)(isAuthenticated(MyApp));
To trochę denerwujące, że trzeba to zrobić na każdej stronie, a następnie przekazać prop do globalnego układu na każdej stronie zamiast po prostu zrobić to raz w „_app.tsx”.
Zgaduję, że powodem może być to, że „_app.tsx” jest składnikiem klasy, a nie składnikiem funkcji takim jak reszta stron? Nie wiem, tylko zgaduję.
Jakaś pomoc w tym?
źródło
ReactJS
podąża za programowaniem funkcjonalnym ani OOP, ale widzę sposób myślenia o rozwoju zaplecza w twoim kodzie z myślami OOP. Dziedzicz nową klasę po innym elemencie! Before Nie widziałem tak wcześniej.