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

React点击提交按钮时如何重置自定义表单组件的state为默认值

核心遗漏要点

React的组件内部状态是私有的,外部组件默认无权直接访问或修改。你当前把TextField、NumberField的输入值都存储在各自组件的内部state中,作为父组件的App以及全局提交函数没有权限操作这些子组件的内部状态,自然无法触发重置。

解决方案1:状态提升(推荐)

将所有表单字段的状态统一放到公共父组件App中管理,通过props把字段值和状态更新方法传递给子组件,提交时直接修改App的状态即可同步到所有子组件,也更方便后续做表单校验、数据收集等逻辑。
修改后的完整代码如下:

import './App.css';
import React from 'react';

// 子组件改为受控组件,值和修改逻辑由父组件传入
const NumberField = (props) => {
  const increment = () => {
    props.onChange(props.value + 1)
  }
  const decrement = () => {
    props.onChange(Math.max(0, props.value - 1))
  }
  const changeHandler = (e) => {
    const val = parseInt(e.target.value) || 0
    props.onChange(val)
  }
  return (
    <div>
      <label htmlFor={props.label}>{props.labelName}</label>
      <button onClick={decrement}>-</button>
      <input type="number" 
        name={props.label} 
        id={props.label} 
        value={props.value}
        onChange={changeHandler}>
      </input>
      <button onClick={increment}>+</button>
    </div>
  );
}

const TextField = (props) => {
  const changeHandler = (e) => {
    props.onChange(e.target.value)
  }
  return (
    <div>
      <label htmlFor={props.label}>{props.labelName}</label>
      <input 
        type="text" 
        name={props.label} 
        id={props.label} 
        placeholder={props.placeholder}
        value={props.value}
        onChange={changeHandler}
      />
    </div>
  );
}

class App extends React.Component {
  constructor(props) {
    super(props);
    // 初始状态统一存在父组件
    this.state = {
      ferry_name: "",
      seats: 0
    }
  }

  handleSubmit = (e) => {
    e.preventDefault();
    console.log("Form Submitted", this.state);
    // 直接重置父组件状态即可同步到所有子组件
    this.setState({
      ferry_name: "",
      seats: 0
    })
  }

  // 统一的状态更新方法
  handleFieldChange = (fieldName, value) => {
    this.setState({
      [fieldName]: value
    })
  }

  render() {
    return (
      <div className="App">
        <div className="AppForm">
          <TextField 
            labelName="Ferry Name" 
            label="ferry_name" 
            placeholder="Enter the ferry name"
            value={this.state.ferry_name}
            onChange={(val) => this.handleFieldChange('ferry_name', val)}
          />
          <div>
            <NumberField 
              labelName="Number of seats" 
              label="seats"
              value={this.state.seats}
              onChange={(val) => this.handleFieldChange('seats', val)}
            />
          </div>
          <div className="formSubmit">
            <button onClick={this.handleSubmit}>Book Ferry</button>
          </div>
        </div>
      </div>
    );
  }
}

export default App;

解决方案2:使用ref调用子组件重置方法(适配现有代码改动最小)

如果不想调整现有状态结构,可以给子组件绑定ref,同时在子组件内部暴露reset方法,提交时通过ref调用所有子组件的reset方法即可。
核心改动点示例:

  1. 给子组件添加reset方法
class NumberField extends React.Component {
  // 原有逻辑不变
  reset = () => {
    this.setState({value: 0})
  }
}
class TextField extends React.Component {
  // 原有逻辑不变
  reset = () => {
    this.setState({value: ""})
  }
}
  1. 在App中创建ref绑定到子组件,提交时调用reset
class App extends React.Component {
  constructor(props) {
    super(props);
    this.ferryNameRef = React.createRef()
    this.seatsRef = React.createRef()
  }
  handleSubmit = (e) => {
    e.preventDefault();
    console.log("Form Submitted");
    // 调用所有子组件的reset方法
    this.ferryNameRef.current.reset()
    this.seatsRef.current.reset()
  }
  render() {
    return (
      <div className="App">
        <div className="AppForm">
          <TextField ref={this.ferryNameRef} labelName="Ferry Name" label="ferry_name" placeholder="Enter the ferry name" />
          <div>
            <NumberField ref={this.seatsRef} labelName="Number of seats" label="seats" />
          </div>
          <div className="formSubmit">
            <button onClick={this.handleSubmit}>Book Ferry</button>
          </div>
        </div>
      </div>
    )
  }
}

其他现有代码问题修正
  • React中label的for属性要写为htmlFor,否则无法和输入框关联
  • NumberField中increment、decrement方法未定义,点击会报错
  • NumberField的changeHandler逻辑错误,当前修改的是不存在的item字段,而非存储值的value,输入不会同步显示
  • TextField的输入框未绑定value和onChange,输入内容不会同步到组件state

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 20:15:00