Tenho um caso em que preciso saber se o usuário está logado ou não antes que a página seja renderizada no servidor e enviada de volta para mim usando o Next.js para evitar alterações de cintilação na interface do usuário.
Consegui descobrir como impedir o usuário de acessar algumas páginas se ele já estiver logado usando este componente 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;
};
E isso funciona muito bem.
Agora, como posso criar um componente HOC semelhante para envolvê-lo, digamos "_app.tsx" para que eu possa passar o propulsor "userAuthenticated" para cada página, obtendo o token e descobrindo se ele expirou ou não e com base em esse suporte posso mostrar a interface do usuário adequada ao usuário sem esse efeito irritante de cintilação?
Espero que você possa me ajudar com isso, tentei fazer da mesma maneira que construí o HOC acima, mas não consegui, principalmente porque o Typescript não facilita as coisas com seus erros estranhos :(
Edit == ==========================================
Consegui criar esse componente HOC e passar o profissional userAuthenticated
para cada página como esta ...
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;
};
No entanto, eu tive que quebrar todas as páginas com esse HOC para passar o suporte userAuthenticated
ao layout global que eu tenho, porque não conseguia envolver o componente de classe "_app.tsx" com ele, isso sempre me dá um erro. ..
Isso funciona ...
export default isAuthenticated(Home);
export default isAuthenticated(about);
Mas isso não ...
export default withRedux(configureStore)(isAuthenticated(MyApp));
Portanto, é um pouco chato ter que fazer isso em todas as páginas e depois passar o suporte para o layout global em todas as páginas, em vez de fazê-lo apenas uma vez no "_app.tsx".
Eu estou supondo que o motivo pode ser porque "_app.tsx" é um componente de classe e não um componente de função como o restante das páginas? Eu não sei, estou apenas adivinhando.
Alguma ajuda com isso?
ReactJS
segue a Programação Funcional nem o POO, mas vejo a mentalidade do desenvolvimento de back-end no código com pensamentos OOP. Herdar uma nova classe de outro componente! “Eu não vi como antes.