ReactJS - 非受控元件



正如我們之前學到的,非受控元件不支援基於 React 的表單程式設計。如果不使用 React API,就無法獲取 React DOM 元素(表單元素)的值。獲取 React 元件內容的一種方法是使用 React 的 ref 特性。

React 為其所有 DOM 元素提供了一個 ref 屬性,並提供了一個相應的 API,React.createRef() 來建立一個新的引用(this.ref)。新建立的引用可以附加到表單元素,並且可以在需要時(在驗證和提交期間)使用this.ref.current.value訪問附加的表單元素的值。

非受控元件中的表單程式設計

讓我們一步一步地看看如何在非受控元件中進行表單程式設計。

步驟 1 - 建立一個引用。

this.inputRef = React.createRef();

步驟 2 - 建立一個表單元素。

<input type="text" name="username" />

步驟 3 - 將已建立的引用附加到表單元素。

<input type="text" name="username" ref={this.inputRef} />

要設定輸入元素的預設值,請使用defaultValue屬性而不是value屬性。如果使用 value 屬性,它將在元件的渲染階段更新。

<input type="text" name="username" ref={this.inputRef} defaultValue="default value" />

最後,在驗證和提交期間使用this.inputRef.current.value獲取輸入值。

handleSubmit(e) {
   e.preventDefault();

   alert(this.inputRef.current.value);
}

建立簡單的表單

在本章中,讓我們建立一個簡單的表單,使用非受控元件新增費用條目。

步驟 1 - 首先,使用Create React App 或 Rollup bundler,按照建立 React 應用章節中的說明,建立一個新的 React 應用,react-form-uncontrolled-app

步驟 2 - 在你喜歡的編輯器中開啟應用程式。

在應用程式的根目錄下建立src資料夾。

src資料夾下建立components資料夾。

步驟 3 - 在src資料夾下建立一個檔案,ExpenseForm.css來為元件設定樣式。

input[type=text], input[type=number], input[type=date], select {
   width: 100%;
   padding: 12px 20px;
   margin: 8px 0;
   display: inline-block;
   border: 1px solid #ccc;
   border-radius: 4px;
   box-sizing: border-box;
}

input[type=submit] {
   width: 100%;
   background-color: #4CAF50;
   color: white;
   padding: 14px 20px;
   margin: 8px 0;
   border: none;
   border-radius: 4px;
   cursor: pointer;
}

input[type=submit]:hover {
   background-color: #45a049;
}

input:focus {
   border: 1px solid #d9d5e0;
}

#expenseForm div {
   border-radius: 5px;
   background-color: #f2f2f2;
   padding: 20px;
}

步驟 4 - 在src/components資料夾下建立一個檔案,ExpenseForm.js並開始編輯。

步驟 5 - 匯入 React 庫。

import React from 'react';

匯入ExpenseForm.css檔案。

import './ExpenseForm.css'

建立一個類,ExpenseForm並使用props呼叫建構函式。

class ExpenseForm extends React.Component {
   constructor(props) {
      super(props);
   }
}

為所有輸入欄位建立 React 引用。

this.nameInputRef = React.createRef();
this.amountInputRef = React.createRef();
this.dateInputRef = React.createRef();
this.categoryInputRef = React.createRef();

建立render()方法並新增一個帶有輸入欄位的表單來新增費用專案。

render() {
   return (
      <div id="expenseForm">
         <form>
            <label for="name">Title</label>
            <input type="text" id="name" name="name" placeholder="Enter expense title" />

            <label for="amount">Amount</label>
            <input type="number" id="amount" name="amount" placeholder="Enter expense amount" />

            <label for="date">Spend Date</label>
            <input type="date" id="date" name="date" placeholder="Enter date" />

            <label for="category">Category</label>
            <select id="category" name="category" >
               <option value="">Select</option>
               <option value="Food">Food</option>
               <option value="Entertainment">Entertainment</option>
               <option value="Academic">Academic</option>
            </select>

            <input type="submit" value="Submit" />
         </form>
      </div>
   )
}

為提交操作新增事件處理程式。

onSubmit = (e) => {
   e.preventDefault();

   let item = {};

   item.name = this.nameInputRef.current.value;
   item.amount = this.amountInputRef.current.value;
   item.date = this.dateInputRef.current.value;
   item.category = this.categoryInputRef.current.value;

   alert(JSON.stringify(item));
}

將事件處理程式附加到表單。

render() {
   return (
      <div id="expenseForm">
         <form onSubmit={(e) => this.onSubmit(e)}>
            <label for="name">Title</label>
            <input type="text" id="name" name="name" placeholder="Enter expense title" 
               ref={this.nameInputRef} />

            <label for="amount">Amount</label>
            <input type="number" id="amount" name="amount" placeholder="Enter expense amount" 
               ref={this.amountInputRef} />      

            <label for="date">Spend Date</label>
            <input type="date" id="date" name="date" placeholder="Enter date" 
               ref={this.dateInputRef} />

            <label for="category">Category</label>
            <select id="category" name="category" 
               ref={this.categoryInputRef} >
               <option value="">Select</option>
               <option value="Food">Food</option>
               <option value="Entertainment">Entertainment</option>
               <option value="Academic">Academic</option>
            </select>

            <input type="submit" value="Submit" />
         </form>
      </div>
   )
}

最後,匯出元件。

export default ExpenseForm

下面是ExpenseForm元件的完整程式碼

import React from 'react';
import './ExpenseForm.css'

class ExpenseForm extends React.Component {
   constructor(props) {
      super(props);

      this.nameInputRef = React.createRef();
      this.amountInputRef = React.createRef();
      this.dateInputRef = React.createRef();
      this.categoryInputRef = React.createRef();
   }
   onSubmit = (e) => {
      e.preventDefault();
      let item = {};
      item.name = this.nameInputRef.current.value;
      item.amount = this.amountInputRef.current.value;
      item.date = this.dateInputRef.current.value;
      item.category = this.categoryInputRef.current.value;

      alert(JSON.stringify(item));
   }
   render() {
      return (
         <div id="expenseForm">
            <form onSubmit={(e) => this.onSubmit(e)}>
               <label for="name">Title</label>
               <input type="text" id="name" name="name" placeholder="Enter expense title" 
                  ref={this.nameInputRef} />

               <label for="amount">Amount</label>
               <input type="number" id="amount" name="amount" placeholder="Enter expense amount" 
                  ref={this.amountInputRef} />   

               <label for="date">Spend Date</label>
               <input type="date" id="date" name="date" placeholder="Enter date" 
                  ref={this.dateInputRef} />

               <label for="category">Category</label>
               <select id="category" name="category" 
                  ref={this.categoryInputRef} >
                 <option value="">Select</option>
                 <option value="Food">Food</option>
                 <option value="Entertainment">Entertainment</option>
                 <option value="Academic">Academic</option>
               </select>
              
               <input type="submit" value="Submit" />
           </form>
         </div>
      )
   }
}
export default ExpenseForm;

index.js

接下來,在 src 資料夾下建立一個檔案 index.js 並使用 ExpenseForm 元件。

import React from 'react';
import ReactDOM from 'react-dom';
import ExpenseForm from './components/ExpenseForm'

ReactDOM.render(
   <React.StrictMode>
      <ExpenseForm />
   </React.StrictMode>,
   document.getElementById('root')
);

index.html

最後,在根資料夾下建立一個public資料夾,並建立一個index.html檔案。

<!DOCTYPE html>
<html lang="en">
   <head>
      <meta charset="utf-8">
      <title>React App</title>
   </head>
   <body>
      <div id="root"></div>
      <script type="text/JavaScript" src="./index.js"></script>
   </body>
</html>

接下來,使用 npm 命令啟動應用程式。

npm start

接下來,開啟瀏覽器並在位址列中輸入https://:3000,然後按 Enter 鍵。

root folder

最後,輸入示例費用詳情並點選提交。提交的資料將被收集並在彈出訊息框中顯示。

root folders
廣告