Help us understand the problem. What is going on with this article?

初めてReactを触ってみたが、ログイン周りの決定打が見つからなかったので自分で書いてみた。

初めてReactを触ってみたが、ログイン周りの決定打が見つからなかったので自分で書いてみた

きっかけ

先日Rectを触る機会があり、事前準備として本も読み。自分なりにモチベーションを上げて

いざプログラムを書いてみようとしたところ、ログイン周りについてReact界でのお作法を何も知らんな?ということに気が付きました。

ちなみに読んだ本はこちら

【りあクト! TypeScriptで始めるつらくないReact開発 第2版】
https://booth.pm/ja/items/1312652

いい本です。この本に巡り合えたことに感謝!

少し調べてみたけど、「私はこんな感じで書いてみた」とかは色々出てきますが、ライブラリでサクッと終わらせるものがない・・・ような気がする。。。

で、いろいろ見た結果、自分で書いてみることにした。

色々な人が公開しているプログラムのいいとこどりなので、見た目もすっきりでコード量も少なく良い感じかと思っています。

今回は、メールアドレスとパスワードで認証というシンプルなものです。

環境

ベースは create-react-app を利用しました。

すみません。せっかく本を読んだというのに
javascriptで書いています。typescriptは次回挑戦します。必ず!

ソース

全ては必要ないかと思うのでログイン周りだけ!

動くものはgithubで公開しているので、試してみてください。
https://github.com/tomonoriminegishi/hello-login-app

App.js

Appコンポーネント

react-routerを利用してルーティングをしています。凄くわかりやすくていい!

Authコンポーネントで囲われている部分が認証領域です。

つまり/list1と/list2は、認証していないと表示されない。ということになります。

分かりやすい!

  • Authコンポーネント内のSwitchコンポーネントが冗長的な感じがしますが必要です。
  • Authコンポーネント内のRedirectコンポーネントは、List1とList2以外が指定された場合にエラーとならないようにList1へリダイレクトしているだけです。
import React, { Component } from 'react';
import {
  BrowserRouter as Router,
  Route,
  Switch,
  Redirect,
} from 'react-router-dom';

import Login from './Login';
import Logout from './Logout';
import List1 from './List1';
import List2 from './List2';
import Auth from './Auth';
import User from './User';

export default class App extends Component {
  render() {
    return (
      <Router>
        <Switch>
          <Route exact path="/login" component={Login} />
          <Route exact path="/logout" component={Logout} />
          <Auth>
            <Switch>
              <Route exact path="/list1" component={List1} />
              <Route exact path="/list2" component={List2} />
              <Redirect from="/" to="/List1" />
            </Switch>
          </Auth>
        </Switch>
      </Router>
    );
  }
}


Auth.js

Authコンポーネント

ログイン済みかどうかの判断をしています。

ログインしていなければログイン画面へリダイレクトし、

ログイン済みならばAuthコンポーネントで囲われたコンポーネントを呼び出します。

import React from 'react';
import { Redirect } from 'react-router-dom';
import User from './User';

const Auth = props =>
  User.isLoggedIn() ? props.children : <Redirect to={'/login'} />;

export default Auth;
  • ログイン済みならば、今回は以下が呼び出されています。
<Switch>
  <Route exact path="/list1" component={List1} />
  <Route exact path="/list2" component={List2} />
  <Redirect from="/" to="/List1" />
</Switch>

User.js

Userクラス

ログイン周りの処理は、このクラスに集約しています。

login処理、logout処理、ログイン状態の確認処理は必要です。

その他にユーザー情報の取得や呼び出しなどもこちらで行うと良いかと思います。

状態をlocalStorageに保存することにより、クラス自体は何度作成されても一貫性のある結果が返るようになっています。

class User {
  isLoggedIn = () => this.get('isLoggedIn') === 'true';

  set = (key, value) => localStorage.setItem(key, value);

  get = key => this.getLocalStorage(key);

  getLocalStorage = key => {
    const ret = localStorage.getItem(key);
    if (ret) {
      return ret;
    }
    return null;
  };

  login = async (email, password) => {

    // ログイン処理
    // ログインエラー時には、falseを返してもいいし、returnを別の用途で利用したかったら
    // 例外を出しして呼び出し元でcatchしてもいいかと思います。

    this.set('isLoggedIn', true);

    return true;
  };

  logout = async () => {
    if (this.isLoggedIn()) {
      this.set('isLoggedIn', false);

      // ログアウト処理
      // 他に必要な処理があるのならこちら

    }
  };
}

export default new User();

Reactでログイン周りについてでした。

これだとダメだということがあればぜひ!メッセージください。

githubで公開しています。
https://github.com/tomonoriminegishi/hello-login-app

教えてください

どなたか、React界でスタンダードな認証周りのライブラリや実装方法を教えてください。
skysemi
スカイプで行っているWeb、スマホアプリ、ゲーム等に関係する勉強会のグループです
https://skysemi.org/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away