【问题标题】:Can I avoid submission of a React form before the state of all controlled fields was set在设置所有受控字段的状态之前,我可以避免提交 React 表单吗
【发布时间】:2018-03-13 19:19:56
【问题描述】:

(我知道这是一个简单的问题。在发帖之前我已经尝试在前面的问题中找到答案。关于 setState 是异步的,关于你可以使用回调函数等的问题有很多,但我没有找到类似以下的问题)。

在 React 中实现一个简单的表单时,例如 here 所示的表单(在 controlled components 标题下,也复制在下面):

由于setState 是异步的,因此不能保证该示例有效,对吧? (由于handleSubmit 打印this.state.value,但不能保证它已经设置,当handleSubmit 被调用时)。

有没有办法确保 handleSubmit 仅在表单中所有受控组件的状态更改完成后才被调用(并且不使用 redux 或类似的东西)?

这是从reactjs.org 复制的代码(我复制它是为了确保即使 URL 更改也可以读取它):

lass NameForm extends React.Component {
  constructor(props) {
    super(props);
    this.state = {value: ''};

    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleChange(event) {
    this.setState({value: event.target.value});
  }

  handleSubmit(event) {
    alert('A name was submitted: ' + this.state.value);
    event.preventDefault();
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <label>
          Name:
          <input type="text" value={this.state.value} onChange={this.handleChange} />
        </label>
        <input type="submit" value="Submit" />
      </form>
    );
  }
}

【问题讨论】:

  • 你可以禁用提交按钮...disabled = {this.state.value == ''}
  • 或者,如果您想获得创意,您可以在您的状态中添加一个名为 submittable 的布尔变量。在您的 handleChange 函数(或任何其他更改状态的函数)开始时将其设置为 false,并在函数的逻辑完成时将其设置回 true。然后让你的 handleSubmit 函数在调度提交逻辑之前检查可提交状态是否为真
  • 只有在setState 之后使用this.state 时才会出现您的问题。在盗版中,状态会在用户触发onClick 事件时更新。如果你想立即使用state,你总是可以async handleChange方法然后await setState,但我认为这里没有必要。
  • 谢谢大家! EgorEgorov - 不确定当用户填写所有值时禁用提交按钮是否有意义。 MEnf - 有多个句柄更改...... FisNan - onClick 之前所有状态更新的任何保证?

标签: reactjs redux


【解决方案1】:

如果您想确保在 handleSubmit 内有输入的当前值,请使用传递给 access inputs from a form 的 SyntheticEvent。

lass NameForm extends React.Component {
  constructor(props) {
    super(props);
    this.state = {value: ''};

    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleChange(event) {
    this.setState({value: event.target.value});
  }

  handleSubmit(event) {
    event.preventDefault();

    const form = event.currentTarget;
    const inputValue = form.elements["user_name"].value;
    alert('A name was submitted: ' + inputValue);
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <label>
          Name:
          <input type="text" name="user_name" value={this.state.value} onChange={this.handleChange} />
        </label>
        <input type="submit" value="Submit" />
      </form>
    );
  }
}

【讨论】:

  • 您可以添加我的问题中提供的示例的其他部分,并进行必要的修改吗?
  • 嗯...有趣,我不知道这个功能。它会一直与它的虚拟 dom 一起工作吗?你试过了吗?
  • 是的,我有时在不需要状态时使用它。它应该像 documented 一样工作 - “每个 SyntheticEvent 对象都具有以下属性:... DOMEventTarget currentTarget
  • 是的,支持 DOM,但 react.js 使用的是虚拟 DOM……谢谢。将其作为对示例来源的 react.js 文档的编辑提供并查看他们所说的内容会很有趣... :)
  • 你不明白 Virtual DOM 是什么意思(这是一个误导性的名字)。它不会取代浏览器 API,它只是意味着它保持 html 文档的内部状态(在 JavaScript 对象中)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-18
  • 1970-01-01
  • 2021-11-17
  • 1970-01-01
  • 2017-05-07
  • 1970-01-01
相关资源
最近更新 更多