У меня есть случай, когда мне нужно знать, вошел ли пользователь в систему или нет, прежде чем страница будет обработана на стороне сервера и отправлена мне обратно с помощью Next.js, чтобы избежать мерцания изменений в пользовательском интерфейсе.
Мне удалось выяснить, как запретить пользователю доступ к некоторым страницам, если он уже вошел в систему с использованием этого компонента 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;
};
И это прекрасно работает.
Теперь, как я могу создать аналогичный компонент HOC, чтобы обернуть его, скажем, «_app.tsx», чтобы я мог передавать «userAuthenticated» реквизит каждой отдельной странице, получая токен и выясняя, истек ли он или нет, и основываясь на что я могу показать пользователю правильный интерфейс без этого раздражающего мерцающего эффекта?
Я надеюсь, что вы можете помочь мне с этим, я пытался сделать это так же, как я построил вышеупомянутый HOC, но я не мог сделать это, тем более что Typescript не облегчает это с его странными ошибками :(
Edit == ==========================================
Я смог создать такой компонент HOC и передать про 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;
};
Однако мне пришлось обернуть каждую страницу с помощью этого HOC, чтобы передать реквизит userAuthenticated
имеющемуся у меня глобальному макету, потому что я не смог обернуть его компонентом класса «_app.tsx», он всегда выдает ошибку. ..
Это работает ...
export default isAuthenticated(Home);
export default isAuthenticated(about);
Но это не ...
export default withRedux(configureStore)(isAuthenticated(MyApp));
Так что немного раздражает необходимость делать это на каждой странице, а затем передавать информацию о глобальном макете на каждой странице вместо того, чтобы просто сделать это один раз в «_app.tsx».
Я предполагаю, что причина может быть в том, что "_app.tsx" является компонентом класса, а не компонентом функции, как остальные страницы? Я не знаю, я просто догадываюсь.
Любая помощь с этим?
ReactJS
следует функциональному программированию или ООП, но я вижу образ мышления бэкэнда в вашем коде с мыслями ООП. Унаследуйте новый класс от другого компонента! «Я не видел, как это раньше.