0

问题的背景

HOC

在处理Next.Js页面时,一种常见的做法是使用HOC(Higher-Order Component) 来避免重新键入页面的基础。

例如,身份验证HOC 可用于检查用户是否经过身份验证。根据结果​​,用户可以访问该页面或被重定向到登录页面。

布局

Next.Js程序员常用的另一种做法是Persistent Layouts. 持久布局是页面上的一个“区域”,当用户浏览页面时不会重新呈现。这对 UX(用户体验)非常有用,例如,菜单的滚动位置保持在页面切换上。

一些不错的链接

NextJs.org - 持久布局文档

CheatCode.co - 如何处理经过身份验证的路由(下面使用的 HOC)

问题

当结合这两种做法时,就会出现持久性问题。(阅读里面的评论AuthenticationRoute.js

这是一个非常简单的index.js

import authenticatedRoute from '@components/auth/AuthenticatedRoute';

const App = () => {
  return (
    <section>
      <h1>Logged In</h1>
      <h1>App</h1>
    </section>
  );
};

export default authenticatedRoute(App);

布局Layout.js

import Link from 'next/link';

import Navbar from '@components/layouts/Navbar';
import SideMenu from '@components/layouts/SideMenu';

function Layout({ children }) {

  const baseUrl = '/app';

  return (
    <section>
      <Navbar>
        <li>
          <Link href={`${baseUrl}/`}>Home</Link>
        </li>
        <li>
          <Link href={`${baseUrl}/test1`}>Test 1</Link>
        </li>
        <li>
          <Link href={`${baseUrl}/test2`}>Test 2</Link>
        </li>
      </Navbar>
      <main>{children}</main>
    </section>;
  );
}

export default Layout;

最后是 HOCAuthenticationRoute.js

import { Component as component } from 'react';
import Router from 'next/router';

import Layout from '@components/layouts/app/Layout';

const authenticatedRoute = (Component = null, options = {}) => {
  class AuthenticatedRoute extends component {
    state = {
      loading: true,
    };

    componentDidMount() {
      const isSignedIn = true;

      if (isSignedIn) {
        this.setState({ loading: false });
      } else {
        Router.push(options.pathAfterFailure || '/sign_in');
      }
    }

    render() {
      const { loading } = this.state;

      if (loading) {
        return <div />;
      }

      // This will return the page without the layout
      return <Component {...this.props} />;

      // Removing the line above and using this instead
      // the page now renders with the layout. BUT...
      // The layout is not persistent, it will re-render
      // everytime a user navigate.
      const getLayout = (page) => <Layout>{page}</Layout>;
      return getLayout(<Component {...this.props} />);


    }
  }

  return AuthenticatedRoute;
};

export default authenticatedRoute;

没有 HOC

index.js当不调用authenticatedRoute时,这在里面工作:

App.getLayout = getLayout;

export default App;

所以我的猜测是 authenticatedRoute 应该返回别的东西return <Component {...this.props} />;

4

0 回答 0