React类组件转函数组件遇阻,参考指定教程操作仍存在困难
React类组件转函数组件错误修复方案
存在的问题清单
- 函数组件无
this上下文,你代码中多处使用this.state、this.setState属于类组件写法,会直接报错 - 用单个
useState存储聚合状态时,每次调用setState必须先展开原有状态...state,否则其余字段会被覆盖丢失 - 输入框
value绑定错误,没有指向对应字段的value属性,会导致输入异常 - 多处未正确从
state对象读取属性,直接调用未定义变量会触发报错 - 同一事件内多次调用
setState存在异步更新覆盖问题,需要合并为单次更新
修复后可运行完整代码
import React,{useState} from 'react' function Rowadd() { const [state, setState] = useState({ flag: false, fields: [], Namefield: { value: '', error: '' }, Emailfield: { value: '', error: '' }, Mobilefield: { value: '', error: '' }, tablerows: [] }); const handleName = (e) => { setState({ ...state, Namefield: { value: e.target.value, error: false } }) }; const handleMobile = (e) => { setState({ ...state, Mobilefield: { value: e.target.value, error: false } }) }; const handleMail = (e) => { setState({ ...state, Emailfield: { value: e.target.value, error: false } }) }; const addRow = (e) => { e.preventDefault(); const newdata = { name: state.Namefield.value, mobile: state.Mobilefield.value, mail: state.Emailfield.value } // 合并状态更新,避免异步覆盖问题 let newFields = [...state.fields] let newNameField = {...state.Namefield} let newMobileField = {...state.Mobilefield} let newEmailField = {...state.Emailfield} if (state.Namefield.value !== "") { newFields.push(state.Namefield) newNameField = { value: '', error: '' } } if (state.Mobilefield.value !== "") { newFields.push(state.Mobilefield) newMobileField = { value: '', error: '' } } if (state.Emailfield.value !== "") { newFields.push(state.Emailfield) newEmailField = { value: '', error: '' } } setState({ ...state, tablerows: state.tablerows.concat(newdata), flag: true, fields: newFields, Namefield: newNameField, Mobilefield: newMobileField, Emailfield: newEmailField }); } const deleteRow = (passedID) => { let tablerows = [...state.tablerows] tablerows.splice(passedID, 1) setState({ ...state, tablerows: tablerows }) } const editRow = (index, type, values) => { const newState = state.tablerows.map((item, i) => { if (i === index) { return { ...item, [type]: values }; } return item; }); setState({ ...state, tablerows: newState }); } return ( <div> <header className="App-header">Sample CRUD Operations</header> <form > <input type="text" placeholder="Name" value={state.Namefield.value} onChange={handleName} /> <br /> <input type="number" placeholder="Mobile" maxLength="10" value={state.Mobilefield.value} onChange={handleMobile} /> <br /> <input type="email" placeholder="Email" value={state.Emailfield.value} onChange={handleMail} /> <br /> <div> <button onClick={addRow}>ADD</button> </div> </form> {state.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> {state.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> ); } export default Rowadd
内容的提问来源于stack exchange,提问作者Amrit chhetri
相关产品推荐
相关产品推荐

