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

React表单提交时最后一项输入无法保存的问题及解决

训练数据收集React组件的状态更新延迟问题

我开发了一个React组件,用于收集用户在多个输入框中的训练数据,提交时将数据发送至后端。但发现每次最后一项输入无法被提交;当新增输入项时,之前“丢失”的输入才会被发送,说明数据存在延迟更新。

SingleSet组件(用户输入项)

function SingleSet(props) {
    const setInitialValue = {
        id: props.id,
        weight: props.weight,
        sets: props.sets,
        reps: props.reps,
    }

    const [currentSetValue, updateSetValue] = useState(setInitialValue);

    function handleWeightChange(e) {
        // update weight
        const setWithUpdatedWeight = currentSetValue;
        setWithUpdatedWeight.weight = e.target.value;
        updateSetValue(setWithUpdatedWeight);
        // send to father
        props.handleSetChange(currentSetValue.id, currentSetValue.weight,
        currentSetValue.sets, currentSetValue.reps);
    }
}

SingleExercise组件(父组件)

function SingleExercise(props) {
    const initialListOfSets = props.setLog;

    const emptySet = {
        id: null,
        weight: null,
        sets: null,
        reps: null,
    }

    const [currentSetList, setSetList] = useState(initialListOfSets);
    
    function handleSetChange(id, changedWeight, changedSets,
        changedReps) {
        const changedSetList = currentSetList.map((set) =>
        {
            if (id === set.id) {
                return {...set, weight: changedWeight,
                sets: changedSets, reps: changedReps}
            }
            return set;
        });
        setSetList(changedSetList);
        props.handleExerciseChange(props.id, currentExerciseName,
            currentSetList);
    }
}

WorkoutLog组件(祖父组件/提交按钮所在组件)

function WorkoutLog(props) {
    const emptyExercise = {
        id: null,
        exerciseName: 'Squat',
        setLog: [
        {id: null, weight: null, sets: null, reps: null},
      ]
    }

    const initialExerciseList = props.isPrefilled? props.data :
    [createEmptyExerciseWithId()];
    
    const [currentExerciseList, setExerciseList] = useState(initialExerciseList);

    function handleExerciseChange(id, changedExerciseName, 
        changedExerciseSetLog) {
            const editedExerciseList = currentExerciseList.map((exercise) =>
            {
                if (id === exercise.id) {
                    return { ...exercise,
                        exerciseName: changedExerciseName,
                        setLog: changedExerciseSetLog};
                }
                return exercise;
            });
            setExerciseList(editedExerciseList);
    }

    const handleSubmit = async (e) => {
        e.preventDefault();
        const response = await fetch('http://localhost:5000/new', {
            method: 'POST',
            body: JSON.stringify(currentExerciseList),
            headers: {
                'Content-Type': 'application/json'
            }
        });
    }
}

我在每个处理onChange的组件中都更新了state,但仍无法解决最后一项输入不更新的问题。


问题解决:传递数据副本替代state

我通过向父组件(提交按钮所在组件)传递数据副本而非子组件的state数据解决了该问题(尽管子组件传递前数据正确,但父组件读取时总是滞后一次更新)。修改后的代码如下:

function handleSetChange(id, changedWeight, changedSets,
        changedReps) {
        const changedSetList = currentSetList.map((set) =>
        {
            if (id === set.id) {
                return {...set, weight: changedWeight,
                sets: changedSets, reps: changedReps}
            }
            return set;
        });
        setSetList(changedSetList);
        props.handleExerciseChange(props.id, currentExerciseName,
            changedSetList);
        // 这里传递changedSetList而非currentSetList
        // 因为父组件之前无法正确更新(总是慢一次变化),现在能正常工作了
    }

    function handleNameChange(e) {
        e.preventDefault();
        // 更新新名称并传递给父组件
        const changedExerciseName = e.target.value;
        setExerciseName(e.target.value);
        props.handleExerciseChange(props.id, changedExerciseName,
            currentSetList);
        // 传递changedExerciseName而非state中的name,修复父组件不更新的问题
    }

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 22:15:04