如何将React类组件转换为使用Hooks的函数式组件(附CRUD示例)
React类组件转函数式组件实现方案
核心转换规则
- 类组件的
this.state统一替换为useStateHook声明的状态,状态更新时对象类型需要手动展开旧值实现合并更新(类组件的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
相关产品推荐
相关产品推荐

