You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将React类组件转换为使用Hooks的函数式组件(附CRUD示例)

React类组件转函数式组件实现方案

核心转换规则

  • 类组件的this.state统一替换为useState Hook声明的状态,状态更新时对象类型需要手动展开旧值实现合并更新(类组件的setState自带合并,Hook的set方法是全量替换)
  • 类中的实例方法直接写为普通函数,不需要额外bind绑定this
  • 移除render()方法,直接return JSX结构
  • 所有this.state.xxx替换为对应声明的状态变量,this.setState替换为useState返回的更新函数

转换后完整代码(和原类组件功能完全一致)

import React, { useState } from 'react'

export default function App(props) {
  // 对应原类组件constructor中初始化的state
  const [flag, setFlag] = useState(false)
  const [fields, setFields] = useState([])
  const [Namefield, setNamefield] = useState({ value: '', error: '' })
  const [Emailfield, setEmailfield] = useState({ value: '', error: '' })
  const [Mobilefield, setMobilefield] = useState({ value: '', error: '' })
  const [tablerows, setTablerows] = useState([])

  // 对应原handleName方法
  const handleName = (e) => {
    setNamefield({
      value: e.target.value,
      error: false
    })
  }

  // 对应原handleMobile方法
  const handleMobile = (e) => {
    setMobilefield({
      value: e.target.value,
      error: false
    })
  }

  // 对应原handleMail方法
  const handleMail = (e) => {
    setEmailfield({
      value: e.target.value,
      error: false
    })
  }

  // 对应原addRow方法
  const addRow = (e) => {
    e.preventDefault()
    const newdata = { name: Namefield.value, mobile: Mobilefield.value, mail: Emailfield.value }
    setTablerows(tablerows.concat(newdata))
    setFlag(true)

    const name1 = Namefield
    const mob1 = Mobilefield
    const mail1 = Emailfield

    if (name1.value !== "") {
      const newName = [...fields, name1]
      setFields(newName)
      setNamefield({ value: '', error: '' })
    }

    if (mob1.value !== "") {
      const newMob = [...fields, mob1]
      setFields(newMob)
      setMobilefield({ value: '', error: '' })
    }

    if (mail1.value !== "") {
      const newMail = [...fields, mail1]
      setFields(newMail)
      setEmailfield({ value: '', error: '' })
    }
  }

  // 对应原deleteRow方法
  const deleteRow = (passedID) => {
    let newTablerows = [...tablerows]
    newTablerows.splice(passedID, 1)
    setTablerows(newTablerows)
  }

  // 对应原editRow方法
  const editRow = (index, type, values) => {
    const newState = tablerows.map((item, i) => {
      if (i === index) {
        return { ...item, [type]: values }
      }
      return item
    })
    setTablerows(newState)
  }

  // 对应原render方法的返回内容
  return (
    <div className="App">
      <header className="App-header">Sample CRUD Operations</header>
      <form>
        <input
          type="text"
          placeholder="Name"
          value={Namefield.value}
          onChange={handleName} />
        <br />
        <input
          type="number"
          placeholder="Mobile"
          maxLength="10"
          value={Mobilefield.value}
          onChange={handleMobile} />
        <br />
        <input
          type="email"
          placeholder="Email"
          value={Emailfield.value}
          onChange={handleMail} />
        <br />
        <div>
          <button onClick={addRow}>ADD</button>
        </div>
      </form>

      {tablerows.length > 0 ?
        <table style={{ "backgroundColor": "rgb(192, 217, 236)" }}>
          <thead style={{ "backgroundColor": "rgb(73, 116, 201)", "color": "white" }}>
            <tr style={{ "height": "50px" }}>
              <th>Name</th>
              <th>Mobile</th>
              <th>Email</th>
              <th>Delete</th>
            </tr>
          </thead>
          <tbody>
            {tablerows.map((row, index) =>
              <tr key={index}>
                <td> <input
                  type="text"
                  value={row.name}
                  onChange={(e) => editRow(index, "name", e.target.value)} /></td>
                <td> <input
                  type="number"
                  maxLength="10"
                  value={row.mobile}
                  onChange={(e) => editRow(index, "mobile", e.target.value)} /></td>
                <td> <input
                  type="email"
                  value={row.mail}
                  onChange={(e) => editRow(index, "mail", e.target.value)} /></td>
                <td><button className="deleteBtn" onClick={() => deleteRow(index)}>-</button></td>
              </tr>)}
          </tbody>
        </table> : ""}
    </div>
  )
}

内容的提问来源于stack exchange,提问作者nisma pokharel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 01:54:00