简体   繁体   中英

Cannot pass ID variable into React form's onSubmit function

I have a React/Redux application using axios to make requests to an express backend.

I am trying to submit a form to the backend route /api/patients/outcomes/:id - where :id is the MongoDB ID for the specific patient whom the data in the form belongs to. On the backend the route adds the form data to an 'outcomes' array on the patient object.

I am having trouble getting the :id into the onSubmit function. When the component with the form is rendered, I have a patients object in Redux that contains the patient's information from the database; the Redux state when component loads is as following:

Redux state
|
|-- patients
|   |-- patients [list of all patients - irrelevent to this component]
|   +-- patient {patient object}
|       |-- _id 
|       |-- name
|       +-- contactInfo {object with contact info}
|
|-- auth
|   |-- isAuthenticated
|   +-- user
|
+-- errors

I have mapped state to props , i've pulled the patient object out of props, i've bound the onSubmit function in the call and I have passed the patient._id into the bind() , however it does not carry to the onSubmit function and thus isn't being passed into the redux action call and in turn not being assigned to the route mentioned above for the axios.post request.

Can anyone see what I am doing wrong here - been at it for a few hours and have made no progress!

The React container that holds the form is as follows (I've truncated the HTML for convenience but it is fundamentally identical)

SubmitOutcome.js

// imports
import React, { Component } from 'react';
import { Link } from 'react-router-dom';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';

// components
import Navbar from '../components/layout/Navbar';
import Sidebar from '../components/layout/Sidebar';

// redux actions
import { submitOutcomeMeasure } from '../redux/actions/patientActions';

class SubmitOutcome extends Component {
  constructor() {
    super();
    this.state = { dateOfTesting: '', measure: '' };
  }

  // event handlers
  onChange = e => {
    this.setState({ [e.target.name]: e.target.value });
  };

  onSubmit = patient_id => e => {
    e.preventDefault();
    const outcomeData = {
      dateOfTesting: this.state.dateOfTesting,
      measure: this.state.measure
    };
    this.props.submitOutcomeMeasure(outcomeData, patient_id,  this.props.history);
  };

  render() {
    const { patient } = this.props.patients;

    return (
      <>
        <Navbar />
        <div className="app-body">
          <Sidebar />
          <main className="main">
            <div className="container">
              <form onSubmit={this.onSubmit.bind(this, patient._id)}>
                <div>
                  <input
                    type="date"
                    name="dateOfTesting"
                    value={this.state.dateOfTesting}
                    onChange={this.onChange}
                  />
                  <input
                    type="text"
                    name="measure"
                    value={this.state.measure}
                    onChange={this.onChange}
                  />
                </div>
                <div>
                  <Link to="/patients" className="btn btn-light mr-2">
                    Cancel
                  </Link>
                  <button type="submit" className="btn btn-primary">
                    Submit
                  </button>
                </div>
              </form>
            </div>
          </main>
        </div>
      </>
    );
  }
}

SubmitOutcome.propTypes = {
  submitOutcomeMeasure: PropTypes.func.isRequired
};

const mapStateToProps = state => ({
  patients: state.patients
});

export default connect(
  mapStateToProps,
  { submitOutcomeMeasure }
)(SubmitOutcome);

Relevant action from patientActions.js

export const submitOutcomeMeasure = (
  outcomeData,
  id,
  history
) => dispatch => {
  axios
    .post(`/api/patients/outcomes/${id}`, outcomeData)
    .then(res => {
      history.push(`/portal/patients/${id}`);
    })
    .catch(err => {
      dispatch({
        type: GET_ERRORS,
        payload: err.response.data
      });
    });
};

first of all you are using fat arrow so you don't need to bind and you can try this line instead and see if it works .

<form onSubmit={e => this.onSubmit(e, patient._id)}>

and then change the onSubmit definition to look like this

onSubmit = (e, patient_id) => {
    e.preventDefault();
    const outcomeData = {
      dateOfTesting: this.state.dateOfTesting,
      measure: this.state.measure
    };
    this.props.submitOutcomeMeasure(outcomeData, patient_id,  this.props.history);
  };

and see if this works

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM