初めて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へリダイレクトしているだけです。

```javascript
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コンポーネントで囲われたコンポーネントを呼び出します。


```javascript

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;
```

 * ログイン済みならば、今回は以下が呼び出されています。

```javascript

<Switch>
  <Route exact path="/list1" component={List1} />
  <Route exact path="/list2" component={List2} />
  <Redirect from="/" to="/List1" />
</Switch>
```

## User.js

Userクラス

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

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

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

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

```javascript

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界でスタンダードな認証周りのライブラリや実装方法を教えてください。
```