在 React 中处理多个表单

Handling multiple forms in React

我正在尝试制作两个带有 Save 按钮的简单表单以在 React 中工作,但 Save 按钮组件似乎无法看到这两个表单。

我的Form组件如下:

import React from "react";
import { Field, reduxForm } from "redux-form";

const validate = values => {
  const errors = {};
  if (!values.name) {
    errors.name = "Required";
  }

  if (!values.age) {
    errors.age = "Required";
  }

  return errors;
};

const renderField = ({
  input,
  label,
  type,
  value,
  meta: { touched, error, warning }
}) => (
  <div>
    <label>{label}</label>
    <div>
      <input {...input} placeholder={label} type={type} />
      {touched && (error && <span className="error">{error}</span>)}
    </div>
  </div>
);

const Form1 = props => {
  const { handleSubmit } = props;
  return (
    <div>
      <form onSubmit={handleSubmit}>
        <Field name="name" component={renderField} type="text" label="Name" />
        <Field name="age" component={renderField} type="text" label="Age" />
        <button type="submit">Submit</button>
      </form>
    </div>
  );
};

export default reduxForm({
  form: "step1", // a unique identifier for this form
  validate
})(Form1);

而我的SaveButton如下:

import React, { Component } from "react";

export default class SaveButton extends Component {
  constructor(props) {
    super(props);
    this.props = props;
    this.submit = this.submit.bind(this);
  }

  submit() {
    console.log(this.props);
    const { dispatch, forms } = this.props;

    forms.forEach(({ formName, isValid, values, errors }) => {
      if (isValid) {
        console.log(values);
      } else {
        //        dispatch(touch(formName, ...Object.keys(errors)));
      }
    });
  }

  render() {
    return (
      <button type="button" onClick={this.submit}>
        Save
      </button>
    );
  }
}

Sandbox example

单击 Save 会得到 Cannot read property 'forEach' of undefined,因为 forms 未定义且 this.props 为空。任何人都知道为什么无法从 SaveButton 看到表格?

这是因为您的保存按钮不是 form 元素的一部分。因此,要获得您必须手动执行的值。这是我的做法,

我将从 App.js 中将 handleSave 函数作为 prop 传递,例如,

import React, { Component } from "react";
import "./App.css";
import Form1 from "./components/form1/Form";
import Form2 from "./components/form2/Form";
import SaveButton from "./components/SaveButton";
import { connect } from "react-redux";
import {
  submit,
  isValid,
  getFormNames,
  getFormValues,
  getFormSyncErrors,
  touch
} from "redux-form";

class App extends Component {
  constructor(props) {
    super(props);
  }

  render() {
    return (
      <div className="App">
        <header className="App-header">
          <h1 className="App-title">Welcome to React</h1>
        </header>
        <div className="App-intro">
          Form 1:
          <Form1 onSubmit={this.step1} />
          <hr />
          Form : 2
          <Form2 onSubmit={this.step2} />
          <hr />
          <SaveButton handleSave={this.handleSave} />
        </div>
      </div>
    );
  }

  step1(values) {
    console.log(values);
  }

  step2(values) {
    console.log(values);
  }
  handleSave = () => {
    const { dispatch, forms } = this.props;
    console.log(forms);

     forms.forEach(({ formName, isValid, values, errors }) => {
       if (isValid) {
         console.log(values);
       } else {
         //        dispatch(touch(formName, ...Object.keys(errors)));
       }
     });
  }
}

const mapStateToProps = state => {
  return {
    forms: getFormNames()(state).map(formName => ({
      formName,
      isValid: isValid(formName)(state),
      values: getFormValues(formName)(state),
      errors: getFormSyncErrors(formName)(state)
    }))
  };
};

export default connect(mapStateToProps)(App);`

SaveButton.js 中,我将简单地调用该函数,

import React, { Component } from "react";

export default class SaveButton extends Component {
  constructor(props) {
    super(props);
    this.props = props;
  }

  submit = () => {
    this.props.handleSave();
  };

  render() {
    return (
      <button type="button" onClick={this.submit}>
        Save
      </button>
    );
  }
}