iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 24
0
Modern Web

激戰 ReactJS 30天系列 第 24

【Day24】好逼真好寫實好重視使用者個資

看了看成就清單後
發現有幾項沒有寫得很清楚
所以改了一下描述
然後呢
就發現
「挖 我這樣好像用不到表單欸」
經過一番思考
好吧
我就來做一個
好逼真好寫實好重視使用者個資

登入畫面
為了達成成就
就這麼辦了

好逼真好寫實好重視使用者個資的登入畫面

首先我們會需要一些新的狀態資料

// App.jsx

   constructor(){
      super();
      this.state={
         isLogined:false,
         user:"",
      }
      this.login = this.login.bind(this);
      this.logout = this.logout.bind(this);
      this.handleChange = this.handleChange.bind(this);
   }

最基本的要有一個登入與否的識別值
預設狀態是上為登入
另外還要記錄這個使用者是誰
接著
在沒有登入的狀態
理應是不能開始遊戲的
所以我在根組件的位置做一個條件渲染
如果是登入狀態
那就渲染登入的畫面
否則就要請使用者先登入

// App.jsx

   render(){
      if(this.state.isLogined){
         return (
            <div>
               <Router>
                  <div>
                     <h2>Games</h2>
                     <ul>
                        <li><Link to={'/ooxx'}>圈圈叉叉</Link></li>
                        <li><Link to={'/aabb'}>數字猜猜</Link></li>
                        <li><Link to={'/'}>回首頁</Link></li>
                     </ul>
                     <hr/>
                     <Switch>
                        <Route exact path="/"
                               children={
                                 <Home user={this.state.user} onClick={this.logout} />
                                 }  
                        />
                        <Route exact path="/ooxx" component={OX} />
                        <Route exact path='/aabb' component={AB} />
                     </Switch>
                  </div>
               </Router>
            </div>
         );      
      }else{
         return(
            <div>
               <h1>你好,先登入一下如何?</h1>
               <form onSubmit={this.login}>
                  <input type="text" placeholder="請輸入您的大名" onChange={this.handleChange}/>
                  <input type="submit" value="確認" />
               </form>
            </div>
         );
      }
   }

在這裡我有碰到一個問題
呈現登入後畫面的是Home這個組件
可是我是透過 Router 去切換的
那這樣要怎麼把登入的使用者名稱傳遞進去呢?
經過了一番研究
Route標籤有一些特定的屬性
其中有一個children的屬性
其中概念就像特殊 props 的那個 children
可以傳遞整個組件用以往 render 函式的寫法
所以這邊我就將登出的函式以及使用者的名稱透過 props 傳遞進去
並且在Home組件呈現這些資料

// Home.jsx

function Home(props){
    return(
        <div>
            <h1>小小遊戲,大大練習!</h1>
            <p>{props.user} 你好啊~</p>
            <p>歡迎來到 ReactJS 的最終激戰</p>
            <p>這裡是首頁,祝天天開心。</p>
            <input type="button" value="登出" onClick={props.onClick} />
        </div>
        );
}

執行畫面:
https://ithelp.ithome.com.tw/upload/images/20180112/20107674sxdxNe0ynZ.png

另外
好的程式習慣可以幫助後續問題處理有更高的效率
所以我去針對每個有接收 props 的組件使用 PropType
若後面加上資料流的時候稍有不慎傳錯資料
就可以更快地找出問題並且修正
首先是Home組件:

Home.jsx

Home.propTypes = {
    user:propTypes.string.isRequired,
    onClick:propTypes.func
}

Home組件裡我們會使用到使用者的名稱和登出的互動函式
所以這邊傳入兩個props
分別是使用者的名稱user和登出用函式onClick
登入後的畫面一定要完成登入才能看到
所以這邊使用者的名稱被設置成必須
在登出函式被觸發的同時
會清除使用者的名稱為空

// App.jsx

   logout(){
      this.setState({
         isLogined:false,
         user:""
      });
   }

這樣就可以在登入狀態持續持有資料
同時避免因為上個使用者的資料導致可以空白輸入直接登入
另外在輸入是空白狀態的時候點選登入
會出現下面的畫面:
https://ithelp.ithome.com.tw/upload/images/20180112/20107674HFOoP8pbAj.png
利用 javascript 的 alert 函式
在登入事件被觸發但沒有輸入的狀態產生提醒

login(event) {
      if(this.state.user === ""){
         alert("你忘記你的名字啦!");
         return false;
      }else{
         this.setState({
            isLogined: true
         });
      }
}

接著是遊戲的狀態資料
猜數字遊戲:

// ABList.jsx

ABList.propTypes = {
    data:propTypes.object
}

圈圈叉叉:

// OXList.jsx

OXList.propTypes = {
    data: propTypes.object.isRequired
}

今天複習了表單的使用方法和 proptype
還使用了一個新的 Route 標籤屬性 children
寫出了一個簡單的登入畫面
越來越像個樣子了哈哈哈

成就清單

https://ithelp.ithome.com.tw/upload/images/20180112/20107674QYcKJa4InP.png

參考資料

  1. tutorialspoint-ReactJS Tutorial
  2. React 官方文件

>>> 隊友任意門 <<<


Day24 end
by 瑞Ray ( ิ◕㉨◕ ิ)


上一篇
【Day23】 有形才有靈
下一篇
【Day25】一個開始華麗變身~!
系列文
激戰 ReactJS 30天31

尚未有邦友留言

立即登入留言