简体   繁体   English

React JS - 重定向到除主页以外的登录

[英]React JS - Redirect to login except home page

I'm learning to use React JS.我正在学习使用 React JS。 I have the following page.我有以下页面。

  • Home
  • Login登录
  • Note笔记
  • Create Note创建笔记

My case is as follows.我的情况如下。

  1. Home can be accessed without logging in无需登录即可访问首页
  2. Note and create notes cannot be accessed without logging in未登录无法访问注释和创建注释

How to make the case above work?如何使上述情况起作用? Here's the code snippet I made:这是我制作的代码片段:

index.js index.js

import App from "./App";
import * as serviceWorker from "./serviceWorker";

ReactDOM.render(
  <BrowserRouter> // from "react-router-dom"
    <App />
  </BrowserRouter>,
  document.getElementById("root")
);

serviceWorker.unregister();

App.js as entry home page App.js 作为入口主页

import React, { Component } from "react";
import AuthService from "./services/auth.service";
import Routes from "./config/routes";
// Lot of import bootstrap dan font-awesome and css


class App extends Component {
  constructor(props) {
    super(props);
    this.logOut = this.logOut.bind(this);

    this.state = {
      currentUser: undefined,
      backendSupportInformation: undefined,
    };
  }

  componentDidMount() {
    const user = AuthService.getCurrentUser();
    if (user) {
      this.setState({
        currentUser: user,
        backendSupportInformation: user.backend,
      });
    }
  }

  logOut() {
    AuthService.logout();
  }

  render() {
    const { currentUser, backendSupportInformation } = this.state;
    return (
      <div>
        <header>
          <nav className="navbar navbar-expand-sm navbar-dark bg-dark">
            // some of link here
          </nav>
        </header>

        <main role="main" className="container-fluid mt-3">
          <Routes /> // use react-route-dom
        </main>

      </div>
    );
  }
}

export default App;

Routes.js路由.js

import React from "react";
import { Route, Switch } from "react-router-dom";

const Routes = () => {
  return (
    <Switch>
      <Route exact path={["/", "/home"]} component={Home} />
      <Route exact path="/login" component={Login} />
      <Route exact path="/note" component={Note} />
      <Route exact path="/note/create" component={NoteCreate} />
      <Route exact path="/profile" component={Profile} />
    </Switch>
  );
};

export default Routes;

Now i am doing in NoteComponent like this.现在我正在像这样在 NoteComponent 中做。

NoteComponent注意组件

export default class Note extends Component {
  state = {
    redirect: null,
    userReady: false,
  };
  
  componentDidMount() {
    const currentUser = AuthService.getCurrentUser();
    
    if (!currentUser) this.setState({ redirect: "/home" });
    this.setState({ currentUser: currentUser, userReady: true });

    this.retrieveAll();
  }

  render() {
    if (this.state.redirect) {
      
      // pass message that you need login first to access this note page
      return <Redirect to={this.state.redirect} />;
    }
}

I dont want to repeat my self into NoteCreate Component?我不想在 NoteCreate 组件中重复我自己? Any advice it so appreciated.它非常感谢任何建议。

Just as a note to start, not sure which resources you're using to learn React, but as of now I would highly recommend you look into a modern course which teaches React with Hooks , aside from to get error boundaries (which with react-error-boundary ) there is no reason to be writing class components.就像开始的注释一样,不确定您使用哪些资源来学习 React,但到目前为止,我强烈建议您查看一门现代课程,该课程使用 Hooks 教授 React ,除了获取错误边界(使用react- error-boundary ) 没有理由编写 class 组件。

Regarding the issue at hand, you didn't specifically mention any errors so this seems to be a question of "how should I go about this" as opposed to actually fixing something?关于手头的问题,您没有特别提到任何错误,所以这似乎是一个问题“我应该如何处理这个问题”而不是实际修复一些东西? Let me know if theres specific errors and I'll try to adjust my answer to help further.让我知道是否存在特定错误,我会尝试调整我的答案以提供进一步帮助。

I would recommend refactoring the logic you have in your Note component into a component of itself, so that you can wrap your routes with it.我建议将您在 Note 组件中的逻辑重构为自身的组件,以便您可以用它来包装您的路由。 Store the information for whether they're authenticated into a context , and then wrap your routes with that context provider so you can consume that context in your child components, without duplicating that logic on each page.将有关它们是否已通过身份验证的信息存储到context 中,然后使用该上下文提供程序包装您的路由,以便您可以在子组件中使用该上下文,而无需在每个页面上重复该逻辑。

You need to create a RouterWithAuth Component and use that instead of using Router directly, something like this:您需要创建一个RouterWithAuth组件并使用它而不是直接使用Router ,如下所示:

export default class RouteWithAuth extends Component {
  state = {
    redirect: null,
    userReady: false,
  };

  componentDidMount() {
    const currentUser = AuthService.getCurrentUser();

    if (!currentUser) this.setState({ redirect: "/home" });
    this.setState({ currentUser: currentUser, userReady: true });

    this.retrieveAll();
  }

  render() {
    const { redirect, userReady } = this.state;

    if (redirect) {
      // pass message that you need login first to access this note page
      return <Redirect to={this.state.redirect} />;
    } else if (userReady) {
      return (
        <Route
          exact={props.exact}
          path={props.path}
          component={props.component}
        />
      );
    } else {
      return <div>Loading....</div>;
    }
  }
}

which a cleaner way of creating RouteWithAuth might be to use React Function Component like this:创建RouteWithAuth的一种更简洁的方法可能是使用React Function Component ,如下所示:


export default function RouteWithAuth() {
  const [redirect, setRedirect] = useState(null);
  const [userReady, setUserReady] = useState(false);

  useEffect(() => {
    const currentUser = AuthService.getCurrentUser();

    if (!currentUser) {
      setRedirect("/home");
      return;
    }

    //Do Something with the currentUser such as storing it in redux store or in context for later use cases
    setUserReady(true);
  }, []);

  if (redirect) {
    return <Redirect to={redirect} />;
  } else if (userReady) {
    return (
      <Route
        exact={props.exact}
        path={props.path}
        component={props.component}
      />
    );
  } else {
    return <div>Loading....</div>;
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM