iT邦幫忙

2025 iThome 鐵人賽

DAY 21
0
Modern Web

30天入門:學會第一個前端框架-React系列 第 21

Day 21 | React入門:React 中的表單 ( Form )

  • 分享至 

  • xImage
  •  

為什麼需要表單

表單是網站中,收集使用者資料的主要方式,例如我們常登入社群所需要的帳號密碼,甚至是貼文底下的留言,都是一種表單。

React 的表單和一般 HTML 表單不同,React 是透過 state 管理輸入值,讓資料與 UI 同步。

一般 HTML 表單 vs. React 表單

比較

一般 HTML 表單 React 表單
資料存放位置 值存在 DOM,需要用 document.querySelectore.target.value 取得 值存在 state,由 React 管理
UI 與資料同步 UI 自動更新,但程式要額外從 DOM 取值 UI 與 state 綁定在一起,輸入時 onChange 同時更新 state
送出方式 重新整理頁面,送到指定的 action URL 常用 onSubmit 攔截 e.preventDefault(),再用 fetch / axios 請求 API
驗證 使用 requiredpattern 等 HTML 屬性 可自定邏輯,或用套件 (Formik、React Hook Form)
控制方式 天生是非受控(值存在 DOM) 可選擇受控(值放在 state) 或 非受控(用 ref 抓 DOM)

(後續文章會介紹到驗證及控制方式)

表單教學-新增 Blog 範例

1. 建立狀態來存放輸入值

const [title, setTitle] = useState("");
  • 使用 useState 為表單中每個欄位建立自己的 state
  • 每次使用者輸入時,React 的 state 會即時更新,確保 UI 和資料保持同步

2.建立受控表單元素

<input 
  type="text" 
  required 
  value={title}
  onChange={(e) => setTitle(e.target.value)}
/>
  • value={title}:此欄位的值綁定到 title 這個 state
  • onChange={(e) => setTitle(e.target.value)}:每當使用者輸入時,React 會即時更新 state

input 是 受控元件 (Controlled Component),因為它輸入值轉而由 React 的 state 掌控,並且透過 onChange 即時更新 state。

3. 表單送出事件

搭配 onSubmit,使用者點擊新增時,執行送出事件

const handleSubmit = (e) => {
  e.preventDefault();
  const blog = { title };

  console.log(blog);
};
  • e.preventDefault():避免送出表單時重新刷新整個頁面
  • const blog = { title }:建立一個 blog 物件,把 state ( title )收集起來
  • 這裡用 console.log(blog) 測試,之後可以改成用 fetch API 的方式(POST 請求),把資料存到資料庫

4. 完整的表單結構

<form onSubmit={handleSubmit}>
  <label>Blog title:</label>
  <input
    type="text"
    required
    value={title}
    onChange={(e) => setTitle(e.target.value)} 
   />
  <button>新增</button>
</form>
  • <form onSubmit={handleSubmit}>:form 的 onSubmit 屬性會在表單送出時觸發 handleSubmit 函式
  • button 預設是 type="submit",點擊時會觸發表單送出事件

完整程式碼:

import { useState } from "react";

const Create = () => {
  const [title, setTitle] = useState("");
  const [body, setBody] = useState("");
  const [author, setAuthor] = useState("");

  const handleSubmit = (e) => {
    e.preventDefault();
    const blog = { title, body, author };

    console.log(blog);
  }

  return (
    <div className="create">
      <h2>新增 Blog</h2>
      <form onSubmit={handleSubmit}>
        <label>Blog title:</label>
        <input 
          type="text" 
          required 
          value={title}
          onChange={(e) => setTitle(e.target.value)}
        />
        <label>Blog body:</label>
        <textarea
          value={body}
          onChange={(e) => setBody(e.target.value)}
        ></textarea>
        <label>Blog author:</label>
        <input
          type="text"
          required
          value={author}
          onChange={(e) => setAuthor(e.target.value)}
        >
        </input>
        <button>新增</button>
      </form>
    </div>
  );
}
 
export default Create;

瀏覽器執行畫面
https://i.meee.com.tw/k5prIos.gif


上一篇
Day 20 | React入門:Nested Routes(巢狀路由)
下一篇
Day 22 | React入門:React 中送出表單資料
系列文
30天入門:學會第一個前端框架-React23
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言