React使ってSPAを作るよ(20)

React使ってSPAを作るよ(20)

React使ってSPAを作るよ目次

React使ってSPAを作るよ(19)の続きです。

前回まではユーザー認証部分を擬似的に判定していましたが、Laravel側でユーザーのAPIを作ってもらったので書き換えていきたいと思います。
(Laravel側の説明ができません。勉強したい)

index.htmlに、ユーザーIDとユーザー名を保持するinput[type=”hidden”]が置いてあります。

@if (!Auth::guest())
<input type="hidden" name="user_id" value="{{ Auth::user()->id }}">
<input type="hidden" name="user_name" value="{{ Auth::user()->name }}">
@endif

サイトにアクセスしてレンダリングする時点でログイン状態ならここにユーザーIDが入ります。
そこで、JSを読み込むときに、先頭であらかじめこのユーザーIDを変数に入れておきます。

var loggedin = $('[name="user_id"]').attr('value');

このあと認証の必要な場面で都度loggedinを見ることになります。
そもそもログインしていなかったらundefinedになり、ログインしていたらユーザーIDを特定できます。

前回の記事で表示/非表示を切り替えていた記事の削除ボタンは、このようになります。

        {(() => {
          if (loggedin === this.props.userId) {
            return <ArticleDelete articleID={this.props.articleID}/>;
          }
        })()}

記事の投稿者のユーザーIDと、閲覧中のユーザーIDが一致していれば削除ボタンを表示します。

※もちろんこれだけだと開発ツールでユーザーIDや記事IDを書き換えたりできてしまうので、実際にAPIを叩くときに認証処理を挟みます。

ユーザーIDがわかればそのユーザーのアイコンのパスもわかるので、ナビゲーションの表示も切り替えられます。
React使ってSPAを作るよ(18)のソースをちょっと修正しましょう。

//ナビゲーションコンポーネント
var Navigation = React.createClass({
  propTypes:{
    text: React.PropTypes.string
  },
  render: function() {
//ユーザーIDがアイコン画像のファイル名になっている想定
    var accountImage = {
      backgroundImage : "url(/images/account/" + loggedin + ".png)" 
    };
    return (
      <nav id="menu">
        <input type="radio" name="menu" id="menu00" defaultChecked="checked" /><label htmlFor="menu00" className="overlay-close">×</label>
        <input type="radio" name="menu" id="menu01"/><label htmlFor="menu01">
          <svg viewBox="0 0 31 37">
            <path d="M26.5,36.5h-22c-2.2,0-4-1.8-4-4v-28c0-2.2,1.8-4,4-4h22
          c2.2,0,4,1.8,4,4v28C30.5,34.7,28.7,36.5,26.5,36.5z M27.5,18.5v-12c0-1.1-0.9-2-2-2h-20c-1.1,0-2,0.9-2,2v12c0,1.1,0.9,2,2,2h20
          C26.6,20.5,27.5,19.6,27.5,18.5z M4.475,26.291h22 M4.475,31.291h22"/>
          </svg>
        </label>
//ログイン判定をloggedinに変更
        {(() => {
          if (loggedin) {
            return <URLForm data={this.props.data} />;
          }
          else {
            return <LoginForm text={'記事を追加するにはログインしてください。'} id={'form-login-save01'} />;
          }
        })()}        
        <input type="radio" name="menu" id="menu02" /><label htmlFor="menu02">
          <svg viewBox="0 0 42.387 43.79">
            <path d="M30.5,15.5c0,8.284-6.716,15-15,15s-15-6.716-15-15s6.716-15,15-15
              S30.5,7.216,30.5,15.5z M15.5,5.5c-5.523,0-10,4.477-10,10s4.477,10,10,10s10-4.477,10-10S21.023,5.5,15.5,5.5z M37.966,39.972
              l-7.221-9.585c-0.993-1.318-2.883-1.584-4.201-0.591l0,0c-1.318,0.993-1.584,2.883-0.591,4.201l7.221,9.585
              c0.993,1.318,2.883,1.584,4.201,0.591l0,0C38.693,43.18,38.959,41.29,37.966,39.972z"/>
          </svg>
        </label>
        <TagList data={this.props.data} />
//ここからナビゲーション右端のアカウントアイコン部分
        <input type="radio" name="menu" id="menu03" />
        {(() => {
          if (loggedin) {
            return <label htmlFor="menu03" style={accountImage}></label>
          }
          else {
            return <label htmlFor="menu03"><svg version="1.1" x="0px" y="0px" viewBox="0 0 27 32.5"><path d="M13.5,0.5c-4.971,0-9,4.029-9,9s4.029,9,9,9s9-4.029,9-9
                  S18.471,0.5,13.5,0.5z M26.5,32c0-6-7.477-10-13-10s-13,4-13,10H26.5z"/></svg></label>
          }
        })()}        
        {(() => {
          if (loggedin) {
            return <Account />;
          }
          else {
            return <LoginForm text={'ログイン'} id={'form-login-save02'} />;
          }
        })()}        
      </nav>
    );
  }
});

とりあえず今回はここまで~
次回はコメントのリストを作ります!

React使ってSPAを作るよ目次