禁用提交按钮,直到以反应最终形式收到来自服务器的答案

时间:2019-09-20 20:32:51

标签: reactjs react-final-form

是否可以用react-final形式的<button disabled={submitting}>禁用Submit按钮,直到收到服务器的答复?服务器响应大约需要6秒钟。但是按钮被禁用了不到一秒钟。这是我的提交功能:

const sleep = ms => new Promise(resolve => setTimeout(resolve, ms))

const onSubmit = async values => {
  await sleep(100)
  let xhr = new XMLHttpRequest();
  xhr.open("POST", "https:...", true) ;
  xhr.setRequestHeader("Content-Type", "application/json");
  let data = {...}
  xhr.send(JSON.stringify(data));
  xhr.onreadystatechange = function() {
    if (xhr.readyState === 4) {
      if (xhr.status === 200) {
        let result = JSON.parse(xhr.responseText);
        if (result.status === "OK") {
          window.location = result.pdf
        };
      }
    }
  };
}

是否可以将submitting设置为true,直到我得到result.status === "OK"

2 个答案:

答案 0 :(得分:0)

您可以执行此操作,但是您需要将提交状态更改为状态。参见下面的示例

import React from 'react'
import { render } from 'react-dom'
import { createForm } from 'final-form'

const sleep = ms => new Promise(resolve => setTimeout(resolve, ms))

const onSubmit = async values => {
  await sleep(300)
  window.alert(JSON.stringify(values, 0, 2))
}

class Form extends React.Component {
  constructor() {
    super()
    const initialState = {}
    let inConstructor = true
    this.form = createForm({ onSubmit })

    // subscribe to form changes
    this.unsubscribe = this.form.subscribe(
      formState => {
        // cannot call setState in constructor, but need to on subsequent notifications
        if (inConstructor) {
          initialState.formState = formState
        } else {
          this.setState({ formState })
        }
      },
      { submitting: true}
    )
    this.state = initialState
    inConstructor = false
  }

  componentWillUnmount() {
    this.unsubscribe()
    this.unsubscribeFields.forEach(unsubscribe => unsubscribe())
  }

  handleSubmit = event => {
    event.preventDefault()
    this.form.submit()
  }

  render() {
    const { formState} = this.state
    return (
        <form onSubmit={this.handleSubmit}>
          <div className="buttons">
            <button type="submit" disabled={formState.submitting}>
              Submit
            </button>
          </div>
          <pre>{JSON.stringify(this.state, 0, 2)}</pre>
        </form>
    )
  }
}

render(<Form />, document.getElementById('root'))

答案 1 :(得分:0)

基于以上答案的第一次编辑,我得到了以下代码:

import React from 'react';
import { Form, Field } from "react-final-form";

type State = {
  submitting: boolean;
}

type Props = {}

const sleep = ms => new Promise(resolve => setTimeout(resolve, ms))

const initialValues = {};

class MyForm extends React.Component<Props, State> {
  state = {
    submitting: false,
  }

  onSubmit = async values => {
    this.setState({
      submitting: true
    })
    await sleep(100)
    let xhr = new XMLHttpRequest();
    xhr.open("POST", "https://...", true) ;
    xhr.setRequestHeader("Content-Type", "application/json");
    let data = {...}
    xhr.send(JSON.stringify(data));
    xhr.onreadystatechange = () => {
      if (xhr.readyState === 4) {
        if (xhr.status === 200) {
          let result = JSON.parse(xhr.responseText);
          if (result.status === "OK") {
            window.location = result.pdf
            this.setState({
              submitting: false
            })
          };
        }
      }
    }
  }

  render() {
    return (
      <Form
        onSubmit={this.onSubmit}
        initialValues={initialValues}
        render={({ handleSubmit, form, invalid, errors, values }) => (
          <form onSubmit={handleSubmit}>
            ...
            <button type="submit" disabled={this.state.submitting}>
                  {this.state.submitting ? 'Downloading': 'Send'}
                </button>
          </form>
        )}
      />
    );
  }
}

export default MyForm;

我会接受前面的答案,但如果您能在注释中更正我的代码中的任何错误,我将不胜感激。