1

I have two models - contact and note. A note belongs to a contact.

I am trying to find a way to reference the contactId in the submit function.

I have passed contactId from a parent to the form:

// parent.js
<NoteNewForm contactId={contactId} onCancel={onCancelNewNoteClick}/>

In my form I want to use this in the submit function. I tried passing it as a param - i.e. submit(contactId) - but this does not work

const submit = (values, dispatch) => {
  var noteData = Object.assign({}, values)

  var primary = {
    type: "notes",
    attributes: noteData
  }

  // I want to use contactId instead of id: "1"
  var relationships = {
    contact: {
      data: {
        type: "contacts",
        id: "1"
      }
    }
  }

  var params = createFormattedParams(primary, relationships)
  dispatch(createNoteForContact(params))
}

export class NoteNewForm extends React.Component {
  constructor(props) {
    super(props)
    this.getValidationState = this.getValidationState.bind(this)
  }

  getValidationState(isError = false, isTouched = false) {
    if (isError && isTouched) {
      return "error"
    } else {
      return null
    }
  }

  render() {
    const {fields: {subject, details, date}, handleSubmit, onCancel, contactId} = this.props
    var extraProps = omit({...date}, 'value')
    return (
      <form onSubmit={handleSubmit(submit)} noValidate autoComplete="off">
        <Row>
          <Col xs={12} sm={6} smPush={6}>
            <FormGroup controlId="date"
                       validationState={this.getValidationState(date.error, date.touched)}>
              <ControlLabel>Date</ControlLabel>
              <DateTimeField
                inputProps={extraProps}
                dateTime={date.value != "" ? date.value : moment().format('YYYY-MM-DD')}
                format="YYYY-MM-DD" inputFormat="DD-MM-YYYY" mode="date"
                onChange={value => date.onChange(value)}
                maxDate={moment()}
              />
              {date.touched && date.error &&
              <HelpBlock>{date.error}</HelpBlock>
              }
              <FormControl.Feedback />
            </FormGroup>
          </Col>
          <Col xs={12} sm={6} smPull={6}>
            <FormGroup controlId="subjectText"
                       validationState={this.getValidationState(subject.error, subject.touched)}>
              <ControlLabel>Subject</ControlLabel>
              <FormControl type="text" {...subject}/>
              {subject.touched && subject.error &&
              <HelpBlock>{subject.error}</HelpBlock>
              }
              {!subject.error && !subject.value &&
              <HelpBlock>Required</HelpBlock>
              }
              <FormControl.Feedback />
            </FormGroup>
          </Col>
        </Row>
        <Row>
          <Col xs={12} sm={12}>
            <FormGroup controlId="detailsText"
                       validationState={this.getValidationState(details.error, details.touched)}>
              <ControlLabel>Details</ControlLabel>
              <FormControl type="text" {...details}/>
              {details.touched && details.error &&
              <HelpBlock>{details.error}</HelpBlock>
              }
              {!details.error && !details.value &&
              <HelpBlock>Required</HelpBlock>
              }
              <FormControl.Feedback />
            </FormGroup>
          </Col>
        </Row>
        <br/>
        <Row>
          <Col xs={12}>
            <div className="pull-right">
              <ButtonToolbar>
                <Button type="submit" className="btn-accent">
                  Create
                </Button>
                <Button type="button" onClick={onCancel}>
                  Cancel
                </Button>
              </ButtonToolbar>
            </div>
          </Col>
        </Row>
      </form>
    )
  }
}

NoteNewForm = reduxForm({
  form: 'NoteNewForm',
  fields: ['subject', 'details', 'date'],
  destroyOnUnmount: false,
  validate
})(NoteNewForm)

export default NoteNewForm

I'm at a loss... Any ideas would be great.

Update! Solved below

I used the suggestion and link from skypecakes and this is the working code:

// the submit function
const submit = (values, dispatch, contactId) => {
  var noteData = Object.assign({}, values)

  var primary = {
    type: "notes",
    attributes: noteData
  }

  var relationships = {
    contact: {
      data: {
        type: "contacts",
        id: contactId
      }
    }
  }

  var params = createFormattedParams(primary, relationships)
  dispatch(createNoteForContact(params))
}

In the form:

  <form onSubmit={handleSubmit((values, dispatch) => {submit(values, dispatch, contactId)})} noValidate
        autoComplete="off">
4

3 回答 3

3

This question is explored in depth in the following question:

Redux-form handleSubmit: How to access store state?

Short answer: You can create a custom submit handler or use mergeprops. Custom submit handler seems cleaner. See the answer for how to use the custom submit handler.

You define your custom submit handler in mapDispatchToProps(), then call it like this:

<form onSubmit={ handleSubmit((values)=>{mySubmitHandler(values, this.props.user);}
于 2016-06-29T21:46:31.410 回答
1

in order to pass some value, you should use .bind(null, value)

 <form onSubmit={handleSubmit(submit.bind(null, contactId ))}
       noValidate autoComplete="off">

then in callback

const submit = (values, dispatch, contactId  ) => {
....
var relationships = {
    contact: {
      data: {
        type: "contacts",
        id: contactId,  //  <---------------------
      }
    }
  }
.....
于 2016-06-29T07:28:20.043 回答
0

better still

Why not have a hidden form field. Set its value through the initialValues prop of your form component. Then in the submit function you receive the values of all fields as a parameter (v6.x.x) only of course

or

The action creator that you pass into your form sendFormData that is called in your submit function can be wrapped / composed with the required data before it's even passed into the form. That way the form has no need or knowledge of the data. It just knows how to collect data and then send it. Single responsibility... E.g.

// Container component wrapping form: Let the code do the talking....

submitNote = (formValues) => {
  this.props.createNoteThunk(this.props.contactId, formValues);
}

render() {

    return (
        <YourForm submitNote={this.submitNote} />
    );
}
于 2016-06-29T12:38:34.360 回答