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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 03:06:03