你如何使用 redux-form 选择器让 syncErrors 脱离状态

How do you get syncErrors out of state using redux-form selectors

所以我有一个 redux-form 组件,它有一个验证函数,returns 值与字段...

const validate = values => {
  const errors = {
    orderHeader: {}
  };

  const orderHeader = values.orderHeader || {};
  if (!orderHeader.orderID) {
    errors.orderHeader.orderID = "Working";
  }
  if (!orderHeader.salesRepID) {
    errors.orderHeader.salesRepID = "Working as well";
  }

  return errors;
}

我正在尝试弄清楚如何使用选择器将所有 syncError 值 return 发送到将列出所有当前错误的错误清单组件。

我的选择器看起来像这样

const selector = formValueSelector('mainForm')
MainForm = connect(
  state =>
  ({
    syncErrors: getFormSyncErrors('mainForm')(state),
    initialValues: state.account.data,
  }
),
  { load: loadAccount }, // bind account loading action creator
)(MainForm);

正在记录以下 return 未定义...

  render() {
    const { error, handleSubmit, load, pristine, reset, submitting, values, syncErrors } = this.props;
    console.log(syncErrors)

我觉得我犯了一个语法错误,因为我希望 return 状态的 syncErrors 部分作为一个对象...它在 form.mainForm.syncErrors 下正确显示状态。

我完全误解了吗?提供什么对我有帮助?

这是完整的组件...

import React from "react";
import ReactDOM from "react-dom";
import { Row, Col, Container, Form } from 'reactstrap';
import classnames from 'classnames'
import store from "../../../store";
import { connect } from 'react-redux';
import axios from 'axios'
import RemoteSubmitButton from '../../ReduxForms/RemoteSubmitButton'
import { Field, reduxForm, formValueSelector, getFormSyncErrors } from 'redux-form';
import { load as loadAccount } from '../../../reducers/account';
import renderInput from '../../ReduxForms/FormComponents';
import submit from '../../ReduxForms/submit'
//import validate from '../../ReduxForms/validate'

const validate = values => {
  const errors = {
    orderHeader: {}
  };

  const orderHeader = values.orderHeader || {};
  if (!orderHeader.orderID) {
    errors.orderHeader.orderID = "Working";
  }
  if (!orderHeader.salesRepID) {
    errors.orderHeader.salesRepID = "Working as well";
  }

  return errors;
}
const remotejson= "SalesObject.json";

class MainForm extends React.Component {
  constructor(props) {
  super(props)
  this.state = {
    data: null,
    }
  }

  componentDidMount () {
  axios.get('/data/' + remotejson)
    .then((response) => {
    //    console.log(response.data);
       this.setState({data: response.data})
     })
    .catch((error)=>{
       //console.log(error);
    });
  }

  render() {
    const { error, handleSubmit, load, pristine, reset, submitting, values, syncErrors } = this.props;
    console.log({syncErrors})
    return (
        <div style={{ padding: 15 }}>
          <Form onSubmit={handleSubmit}>
            <button type="button" onClick={() => load(this.state.data)}>Load Order</button>
            <Container>
              <Row>
                <Col sm={4}>
                  <Field label="order ID" id="orderID" name="orderHeader.orderID" type="text" component={renderInput} />
                </Col>
                <Col sm={4}>
                  <Field id="salesRepID" name="orderHeader.salesRepID" type="text" component={renderInput} />
                </Col>
              </Row>
            </Container>
            {syncErrors && <strong>{syncErrors}</strong>}
            {error && <strong>{error}</strong>}
          </Form>
          <RemoteSubmitButton />
        </div>
    )
  }
}

    // Decorate with reduxForm(). It will read the initialValues prop provided by connect()
let MainReduxForm = MainForm = reduxForm({
  form: 'mainForm', // a unique identifier for this form
  enableReinitialize: true, // Important after the data load process is moved to redux saga. This should allow for a common sales object to be built
  validate,
  onSubmit: submit // submit function must be passed to onSubmit
})(MainForm);

// You have to connect() to any reducers that you wish to connect to yourself
const selector = formValueSelector('mainForm')
MainReduxForm = connect(
  state =>
  ({
    syncErrors: getFormSyncErrors('mainForm')(state),
    initialValues: state.account.data
  }),
  { load: loadAccount }, // bind account loading action creator
)(MainReduxForm);

export default MainReduxForm; 

syncErrors 是 redux-form 内部使用的关键字,不能作为表单组件的道具使用。您需要将 syncError 传递给具有不同名称的组件

class MainForm extends React.Component {
  constructor(props) {
  super(props)
  this.state = {
    data: null,
    }
  }

  componentDidMount () {
  axios.get('/data/' + remotejson)
    .then((response) => {
    //    console.log(response.data);
       this.setState({data: response.data})
     })
    .catch((error)=>{
       //console.log(error);
    });
  }

  render() {
    const { error, handleSubmit, load, pristine, reset, submitting, values, synchronousError } = this.props;
    console.log({syncErrors})
    return (
        <div style={{ padding: 15 }}>
          <Form onSubmit={handleSubmit}>
            <button type="button" onClick={() => load(this.state.data)}>Load Order</button>
            <Container>
              <Row>
                <Col sm={4}>
                  <Field label="order ID" id="orderID" name="orderHeader.orderID" type="text" component={renderInput} />
                </Col>
                <Col sm={4}>
                  <Field id="salesRepID" name="orderHeader.salesRepID" type="text" component={renderInput} />
                </Col>
              </Row>
            </Container>
            {synchronousError && <strong>{synchronousError}</strong>}
            {error && <strong>{error}</strong>}
          </Form>
          <RemoteSubmitButton />
        </div>
    )
  }
}

    // Decorate with reduxForm(). It will read the initialValues prop provided by connect()
let MainReduxForm = reduxForm({
  form: 'mainForm', // a unique identifier for this form
  enableReinitialize: true, // Important after the data load process is moved to redux saga. This should allow for a common sales object to be built
  validate,
  onSubmit: submit // submit function must be passed to onSubmit
})(MainForm);

// You have to connect() to any reducers that you wish to connect to yourself
const selector = formValueSelector('mainForm')
MainReduxForm = connect(
  state =>
  ({
    synchronousError : getFormSyncErrors('mainForm')(state), // change name here
    initialValues: state.account.data
  }),
  { load: loadAccount }, // bind account loading action creator
)(MainReduxForm);

export default MainReduxForm;

我也做了一个demo working codesandbox