Unable to change this.state property: Cannot read property 'setState' of undefined

Viewed 52

Hi guys I'm making a very simple react app, new programmer here, and I'm not able to change the value of 'this.state.isModalOpen' as even when I console log it, it comes as false even though I literally changed it to true in the pervious line. Please help I don't know what is wrong. Thank you

order.form.js

import React, { Component } from 'react';
import './order-form.css';
import axios from 'axios';
import Modal from 'react-modal';

export default class OrderForm extends Component{

    
    constructor(props){
        super(props);

        this.state = {
            nameId : '',
            phoneNu : '',
            emailId : '',
            pizzaSz : '',
            topping : '',
            delivTime : '',
            instru : '',
            isModalOpen : false
        }
    }

    componentDidMount() {
        axios
        .post('http://httpbin.org/post', this.state)
        .then(response => {console.log("Response: " + response)})
        .catch(error => {console.log("Error: " + error)})
    }

    changeHandler = e => {
        this.setState({ [e.target.name] : e.target.value })
      }

     submitHandler = e => {
        e.preventDefault();
        console.log(this.state);
    }

    openModal = e => {
    this.setState({ [e.isModalOpen] : e.true });
    console.log(this.state.isModalOpen)
}

    render() {
        const{ nameId, phoneNu, emailId, pizzaSz, topping, delivTime, instru, 
            isModalOpen } = this.state;
        return(
        <div>
            <form onSubmit={this.submitHandler}>
                <div className="contact-details px-3">
                    Customer name: <input type="text" name="nameId"
                    value={nameId} onChange={this.changeHandler}/><br/>
                    Telephone: <input type="number" name="phoneNu"
                    value={phoneNu} onChange={this.changeHandler}/><br/>
                    E-mail address: <input type="email" name="emailId"
                    value={emailId} onChange={this.changeHandler}/><br/>
                </div>

                <div className="px-3 py-2 pizza-details">
                    <p className="label">Pizza Size<br/></p>
                    <input type="radio" id="sm" name="pizzaSz" value="sm" 
                    onChange={this.changeHandler}/>
                    <label for="sm">Small</label><br/>
                    <input type="radio" id="md" name="pizzaSz" value="md" 
                    onChange={this.changeHandler}/>
                    <label for="md">Medium</label><br/>
                    <input type="radio" id="lg" name="pizzaSz" value="lg" 
                    onChange={this.changeHandler}/>
                    <label for="lg">Large</label><br/>
                </div>
                
                <div className="px-3 py-2 pizza-details">
                    <p className="label">Pizza Topping </p>
                    <input type="checkbox" id="bacon" name="topping"
                    value="bacon" onChange={this.changeHandler}/>
                    <label for="bacon"> Bacon</label><br/>
                    <input type="checkbox" id="excheese" name="topping"
                    value="excheese" onChange={this.changeHandler}/>
                    <label for="excheese"> Extra Cheese</label><br/>
                    <input type="checkbox" id="onion" name="topping"
                    value="onion" onChange={this.changeHandler}/>
                    <label for="onion"> Onion</label><br/>
                    <input type="checkbox" id="mushrm" name="topping"
                    value="mushrm" onChange={this.changeHandler}/>
                    <label for="mushrm">Mushroom</label><br/>
                </div>
                
                <div className="px-3 delivery-details">
                    Preferred Delivery Time: <input type="datetime-local" 
                    name="delivTime" name="delivTime" value={delivTime} 
                    onChange={this.changeHandler}
                    min="2021-07-21T00:00" max="2021-07-28T00:00"/><br/>
        
                    Delivery Intructions: <input type="text" name="instru" id="instru"
                    value={instru} onChange={this.changeHandler}/><br/>

                    <button className="btn btn-primary mt-3" type="submit" 
                    onClick={this.openModal}
                    >Submit Order</button><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
                
                    <Modal isOpen={isModalOpen}>
                        <h2>Hi</h2>
                        <p></p>
                    </Modal>
                </div>
            </form>
        </div>);
    }
}

App.js

import './App.css';
import 'bootstrap/dist/css/bootstrap.min.css';
import OrderForm from './components/order-form';

function App() {
  return (
    <div className="container">
      <div className="row">
        <OrderForm/>
      </div>
    </div>
  );
}

export default App;
1 Answers

You don't need to use e (Event):

this.setState({ isModalOpen : true });

Read more regarding setState on official documentation. The pattern you were using is for dynamic Object properties.

Also as you are using Fat Arrow Fuction you loose context. This is because arrow functions use lexical this (see this similar question). To solve this, as an option, just get rid of arrow function:

openModal(e) {
  this.setState({ isModalOpen: true });
  console.log(this.state.isModalOpen)
}

and bind context to your function inside constructor method:

constructor(props) {
   super(props);
   
   ...
   
   this.openModal = this.openModal.bind(this);
}

There is official explanation on React Docs regarding this https://reactjs.org/docs/faq-functions.html

Related