Tôi có một trường hợp khi tôi cần biết người dùng có đăng nhập hay không trước khi trang được hiển thị phía máy chủ và gửi lại cho tôi bằng Next.js để tránh thay đổi nhấp nháy trong giao diện người dùng.
Tôi đã có thể tìm ra cách ngăn người dùng truy cập vào một số trang nếu anh ta đã đăng nhập bằng thành phần HOC này ...
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;
};
Và điều này làm việc tuyệt vời.
Bây giờ, làm cách nào tôi có thể xây dựng một thành phần HOC tương tự để bọc nó xung quanh, hãy nói "_app.tsx" để tôi có thể chuyển prop "userAuthenticated" cho mỗi trang bằng cách lấy mã thông báo và tìm hiểu xem nó có hết hạn hay không và dựa trên Tôi có thể hiển thị giao diện người dùng phù hợp cho người dùng mà không có hiệu ứng nhấp nháy khó chịu đó không?
Tôi hy vọng bạn có thể giúp tôi với điều đó, tôi đã cố gắng thực hiện giống như cách tôi đã tạo HOC ở trên, nhưng tôi không thể làm điều đó, đặc biệt là Typecript không làm điều này dễ dàng hơn với các lỗi lạ của nó :(
Chỉnh sửa == ==========================================
Tôi đã có thể tạo thành phần HOC như vậy và chuyển pro userAuthenticated
cho từng trang như thế này ...
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;
};
Tuy nhiên, tôi đã phải bọc từng trang với HOC này để chuyển xuống chỗ userAuthenticated
dựa cho bố cục toàn cầu mà tôi có, vì tôi không thể bọc thành phần lớp "_app.tsx" với nó, nó luôn gây ra lỗi cho tôi. ..
Những công việc này ...
export default isAuthenticated(Home);
export default isAuthenticated(about);
Nhưng điều này không ...
export default withRedux(configureStore)(isAuthenticated(MyApp));
Vì vậy, có một chút khó chịu khi phải làm điều này cho từng trang và sau đó chuyển xuống chỗ dựa cho bố cục toàn cầu trong mỗi trang thay vì chỉ thực hiện một lần trong "_app.tsx".
Tôi đoán lý do có thể là do "_app.tsx" là thành phần lớp chứ không phải thành phần chức năng như các trang còn lại? Tôi không biết, tôi chỉ đoán thôi.
Bất kỳ trợ giúp với điều đó?
ReactJS
tuân theo Lập trình chức năng cũng như OOP, nhưng tôi thấy tư duy phát triển phụ trợ trong mã của bạn với những suy nghĩ OOP. Kế thừa một lớp mới từ một thành phần khác! "Tôi không thấy giống như trước đây.