J'ai un cas où j'ai besoin de savoir si l'utilisateur est connecté ou non avant que la page ne soit rendue côté serveur et renvoyée à moi à l'aide de Next.js pour éviter d'avoir des changements de scintillement dans l'interface utilisateur.
J'ai pu comprendre comment empêcher l'utilisateur d'accéder à certaines pages s'il est déjà connecté à l'aide de ce composant 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;
};
Et cela fonctionne très bien.
Maintenant, comment puis-je créer un composant HOC similaire pour l'enrouler, disons "_app.tsx" afin que je puisse passer l'accessoire "userAuthenticated" à chaque page en obtenant le jeton et déterminer s'il est expiré ou non et basé sur cet accessoire, je peux montrer l'interface utilisateur appropriée à l'utilisateur sans cet effet de scintillement ennuyeux?
J'espère que vous pouvez m'aider avec ça, j'ai essayé de le faire de la même manière que j'ai construit le HOC ci-dessus, mais je ne pouvais pas le faire, surtout que Typescript ne rend pas cela plus facile avec ses erreurs étranges :(
Edit == ==========================================
J'ai pu créer un tel composant HOC et transmettre le pro userAuthenticated
à chaque page comme celle-ci ...
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;
};
Cependant, j'ai dû envelopper chaque page avec ce HOC afin de transmettre l'hélice userAuthenticated
à la disposition globale que j'ai, car je ne pouvais pas envelopper le composant de classe "_app.tsx" avec, cela me donne toujours une erreur. ..
Cela marche ...
export default isAuthenticated(Home);
export default isAuthenticated(about);
Mais cela ne veut pas ...
export default withRedux(configureStore)(isAuthenticated(MyApp));
Il est donc un peu ennuyeux de devoir le faire pour chaque page, puis de transmettre l'accessoire à la mise en page globale dans chaque page au lieu de le faire une seule fois dans le "_app.tsx".
Je suppose que la raison peut être parce que "_app.tsx" est un composant de classe et non un composant de fonction comme le reste des pages? Je ne sais pas, je devine.
Une aide avec ça?
ReactJS
suit la programmation fonctionnelle ni la POO, mais je vois l'état d'esprit du développement backend dans votre code avec des pensées POO. Héritez une nouvelle classe d'un autre composant! 😐 Je n'ai jamais vu ça comme ça auparavant.