iT邦幫忙

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

激戰 ReactJS 30天系列 第 14

【Day14】 我問你要答R - Forms

核心的概念在前10天差不多都認識了
常常我們在寫網頁程式的時候
會用到一些互動事件功能
接下來就要來認識在 React 中是怎麼呈現這些比較常見的功能囉~

Forms

常常我們會需要使用者輸入一些資料來幫助網頁的運行
這些資料通常都會透過表單(forms)來做接收
然後再透過 javascript 接續處理資料
在 React 中
有一個專有名詞專門達成這些事項
就叫做 controlled components

controlled components

controlled components 渲染出網頁上的表單之後
同時他也控制著使用者輸入的資訊
透過 setState 同步更新輸入的畫面
讓所有資料呈現統一的狀態

import React from 'react';

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {value: '預設資料'};

    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleChange(event) {
    this.setState({value: event.target.value});
  }

  handleSubmit(event) {
    alert('A name was submitted: ' + this.state.value);
    event.preventDefault();
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <label>
          Name:
          <input type="text" value={this.state.value} onChange={this.handleChange} />
        </label>
        <p>{this.state.value},您好。</p>
        <input type="submit" value="Submit" />
      </form>
    );
  }
}
export default App;

透過onChange事件偵測表單的input(也就是輸入欄位內的內容值)是否發生改變
如果使用者輸入資訊
handleChange函式會被觸發並呼叫組件內的setState函式
透過setState改變組件 state 並且重新渲染
達到同步更新畫面的作用
組件內的狀態資料將會持續維持和使用者輸入一致的狀態
這就是 React 實現表單輸入與資料接收處理的方式
執行結果:
https://ithelp.ithome.com.tw/upload/images/20180102/20107674mLW02OWkj4.png

表單除了簡單短字串的輸入
還有很多諸如簡答、單選或多選的回應形式
下面就讓我們針對不同的輸入方式
做個簡單的小小DEMO測試:

textarea Tag

textarea 是 HTML 中可以輸入更多文字的文字方塊
只要在 state 中初始設定
就能達到類似 placeholder 的作用
讓最開始的欄位中就有基本文字
只需要改變表單內的標籤為textarea
其他原理和上面基本字串輸入相同

import React from 'react';

class App extends React.Component {
   constructor(props) {
      super(props);
      this.state = {
         data: 'try to write something...'
      }
      this.updateState = this.updateState.bind(this);
   };
   updateState(e) {
      this.setState({data: e.target.value});
   }
   render() {
      return (
         <div>
            <Content myDataProp = {this.state.data} 
               updateStateProp = {this.updateState}></Content>
         </div>
      );
   }
}
class Content extends React.Component {
   render() {
      return (
         <div>
            <input type = "text" value = {this.props.myDataProp} 
               onChange = {this.props.updateStateProp} />
            <h3>{this.props.myDataProp}</h3>
         </div>
      );
   }
}
export default App;

執行結果:
https://ithelp.ithome.com.tw/upload/images/20180102/20107674MwrNrpfJLA.png

Select Tag

Select Tag 提供下拉式選單工使用者選擇
運作原理同上
僅需要更改使用的標籤為select

import React from 'react';

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {value: '預設資料'};

    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleChange(event) {
    this.setState({value: event.target.value});
  }

  handleSubmit(event) {
    alert('A name was submitted: ' + this.state.value);
    event.preventDefault();
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <label>
          Name:
          <select value={this.state.value} onChange={this.handleChange}>
            <option value="同學A">同學A</option>
            <option value="老師B">老師B</option>
            <option value="路人C">路人C</option>
            <option value="寵物D">寵物D</option>
          </select>
        </label>
        <p>您選擇的是:{this.state.value}</p>
        <input type="submit" value="Submit" />
      </form>
    );
  }
}
export default App;

執行結果:
https://ithelp.ithome.com.tw/upload/images/20180102/20107674chhGi3owmn.png

Multiple Inputs

通常表單不會只有一個欄位需要填寫
當有複數個不同類型的表單需要填寫的時候
React 中會建議給不同的欄位一個name屬性
在使用者改變其中的欄位時
React 可以透過name判斷是哪一個欄位被填寫
並且對該欄位更新狀態

import React from 'react';

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      isGoing: true,
      numberOfGuests: 2
    };

    this.handleInputChange = this.handleInputChange.bind(this);
  }

  handleInputChange(event) {
    const target = event.target;
    const value = target.type === 'checkbox' ? target.checked : target.value;
    const name = target.name;

    this.setState({
      [name]: value
    });
  }
  render() {
    return (
      <form onSubmit={this.handleSubmit}>
         <label>
          Is going:
          <input
            name="isGoing"
            type="checkbox"
            checked={this.state.isGoing}
            onChange={this.handleInputChange} />
        </label>
        <br />
        <label>
          Number of guests:
          <input
            name="numberOfGuests"
            type="number"
            value={this.state.numberOfGuests}
            onChange={this.handleInputChange} 
            min="0"
            max="10"/>
        </label>
      </form>
    );
  }
}
export default App;

在這段程式碼中共有兩個欄位
分別是核取方塊和數字選單
他們的name屬性值不同
當任一欄位被變動時
onChange會呼叫handleInputChange函式
呼叫的同時將目標(target)傳遞進函式
透過目標的name值讓 React 知道是哪個欄位被更新
在透過setState直接對該欄位的狀態資料變更
[name]Computed property names 的用法
是ES6之後版本的用法
可以讓運算化作變數名稱
並且當成字串被閱讀及使用
在這裡便是透過將name和狀態中的資料同名
來達到選擇欄位進行setState的功效
執行結果:
https://ithelp.ithome.com.tw/upload/images/20180102/20107674qjxyo49emP.png

以上就是 React 中的表單幾個用法
表單是一個互動式網頁取得使用著者資料的一個重要來源
由此可知它的重要性
後面會透過一些實際練習
把這部分在更熟悉一點

參考資料

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

>>> 隊友任意門 <<<


Day14 end
by 瑞Ray (=´ω`=)


上一篇
【Day13】 搭火車排排隊 - Lists and Keys
下一篇
【Day15】 進入最佳狀態 - Lifting State Up
系列文
激戰 ReactJS 30天31

尚未有邦友留言

立即登入留言