1

I am trying to update state value but in meantime it give me an error that TypeError: Cannot read property 'state' of undefined. when I type something in field then click on submit then I got this error . I think it might be silly question to ask but trust me I am new to React . Could someone please help me how to solve this problem , I really need to solve my problem .

Thanks

Code

//ModalComponent.js
import React from "react";
import { Button, Modal, ModalHeader, ModalBody, ModalFooter } from "reactstrap";
import axios from "axios";

export default class ModalComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = { modal: false, subject: "", taskType: "", notes: "" };
  }

  toggle = () => {
    this.setState({
      modal: !this.state.modal
    });
  };
  handleSubject = e => {
    this.setState({ subject: e.target.value });
  };
  handleTaskType = e => {
    this.setState({ taskType: e.target.value });
  };
  handleNotes = e => {
    this.setState({ country: e.target.value });
  };

  handleSubmit(e) {
    e.preventDefault();
    const form = {
      subject: this.state.subject,
      taskType: this.state.taskType,
      notes: this.state.notes
    };
    let uri = "localhost:3000/api/diary/update";
    axios.post(uri, form, { params: { id: 347 } }).then(response => {
      this.setState({
        modal: !this.state.modal
      });
    });
  }

  render() {
    console.log(this.state.subject);
    return (
      <div>
        <h1>React Bootstrap Modal Example</h1>
        <Button color="success" onClick={this.toggle}>
          React Modal
        </Button>
        <Modal isOpen={this.state.modal}>
          <form onSubmit={this.handleSubmit}>
            <ModalHeader>IPL 2018</ModalHeader>
            <ModalBody>
              <div className="row">
                <div className="form-group col-md-4">
                  <label>Subject:</label>
                  <input
                    type="text"
                    name="subject"
                    value={this.state.subject}
                    onChange={this.handleSubject}
                    className="form-control"
                  />
                </div>
              </div>
              <div className="row">
                <div className="form-group col-md-4">
                  <select onChange={this.handleTaskType}>
                    <option>Select Task Type</option>
                    <option value="meeting">Meeting</option>
                    <option value="followUp">Follow Up</option>
                    <option value="reminder">Reminder</option>
                    <option value="other">Other</option>
                  </select>
                </div>
              </div>
              <div className="row">
                <div className="form-group col-md-4">
                  <label>Country:</label>
                  <input
                    type="text"
                    value={this.notes}
                    onChange={this.handleNotes}
                    className="form-control"
                  />
                </div>
              </div>
            </ModalBody>
            <ModalFooter>
              <input
                type="submit"
                value="Submit"
                color="primary"
                className="btn btn-primary"
              />
              <Button color="danger" onClick={this.toggle}>
                Cancel
              </Button>
            </ModalFooter>
          </form>
        </Modal>
      </div>
    );
  }
}
jonny
  • 121
  • 1
  • 3
  • 13

3 Answers3

1

You have to tell your handleSubmit method which this you want to use. As the docs say :

You have to be careful about the meaning of this in JSX callbacks. In JavaScript, class methods are not bound by default. If you forget to bind this.handleClick and pass it to onClick, this will be undefined when the function is actually called.

To do that, you can bind handleSubmit in your constructor like this :

constructor(props) {
    ...
    this.handleSubmit = this.handleSubmit.bind(this);
    ...
} 
Clafouti
  • 4,035
  • 5
  • 30
  • 38
0

setState is asynchronous so there are two options to fix this issue, one is to use arrow function in handleSubmit and the second one is to bind the function.

Code below should solve your problem.

  handleSubmit = e => {
    e.preventDefault();
    const form = {
      subject: this.state.subject,
      taskType: this.state.taskType,
      notes: this.state.notes
    };
    let uri = "localhost:3000/api/diary/update";
    axios.post(uri, form, { params: { id: 347 } }).then(response => {
      this.setState({
        modal: !this.state.modal
      });
    });
  }
Damian Busz
  • 1,693
  • 1
  • 10
  • 22
0

Try This,

 constructor(props) {
    super(props);
    this.state = { modal: false, subject: "", taskType: "", notes: "" };
     this.handleSubmit = this.handleSubmit.bind(this);
     this.handleSubject = this.handleSubject.bind(this);
     this.handleTaskType = this.handleTaskType.bind(this);
     this.handleNotes = this.handleNotes.bind(this);
  }
Dixit Savaliya
  • 413
  • 3
  • 7