Home > Back-end >  Uncaught TypeError - Getting errors after already defining state variable in React component constru
Uncaught TypeError - Getting errors after already defining state variable in React component constru

Time:02-26

I am getting the error: Uncaught TypeError: Cannot read properties of undefined (reading 'state') even though state is defined in the constructor of my React component. I get the error at the line where I set the value of the <input> to {this.state.deckName}

export class DeckForm extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            deckName: '',
            deckList: ''
        };
        // Bind our event handler methods to this class
        this.handleDeckNameChange = this.handleDeckNameChange.bind(this);
        this.handleDeckListChange = this.handleDeckListChange.bind(this);
        this.handleSubmission = this.handleSubmission.bind(this);
    }

    // Event handler method to update the state of the deckName each time a user types into the input form element
    handleDeckNameChange(event) {
        let typed = event.target.value;
        this.setState({ deckName: typed });
    }

    // Event handler method to update the state of the deckList each time a user types into the textarea from element]
    handleDeckListChange(event) {
        let typed = event.target.value;
        this.setState({ deckList: typed });
    }

    // Event handler method to handle validation of deckName and deckList
    handleSubmission(event) {
        console.log(`${this.state.deckName}`);
        console.log(`${this.state.deckList}`)
    }

    render() {
        return (
            <form className='was-validated'>
                <this.DeckName />
                <this.DeckList />
                <button type='submit' className='btn-lg btn-warning mt-3'>Create</button>
            </form>                       
        );
    }

    DeckName() {
        return (
            <div className='form-group mb-3'>
                <input 
                    value={this.state.deckName} /* ERROR HERE */
                    onChange={this.handleDeckNameChange} 
                    type='text' 
                    placeholder='Deck name' 
                    className='form-control' 
                    required
                />
            </div>
        );
    }

    DeckList() {
        let format = 'EXACT CARD NAME 1\nPot of Greed 3\nChange of Heart 3\nGraceful Charity 3'
        return (
            <div className='form-group'>
                <textarea
                    value={this.state.deckList}
                    onChange={this.handleDeckListChange} 
                    className='form-control' 
                    rows='15' 
                    required
                >
                    {format}
                </textarea>
            </div>
        );
    }
}

CodePudding user response:

Use below code it's working for me

https://codesandbox.io/s/weathered-water-jm1ydv?file=/src/App.js

DeckName()  {
    return (
      <div className="form-group mb-3">
        <input
          value={this?.state.deckName} /* ERROR HERE */
          onChange={this?.handleDeckNameChange}
          type="text"
          placeholder="Deck name"
          className="form-control"
          required
        />
      </div>
    );
  }

  DeckList() {
    let format =
      "EXACT CARD NAME 1\nPot of Greed 3\nChange of Heart 3\nGraceful Charity 3";
    return (
      <div className="form-group">
        <textarea
          value={this?.state.deckList}
          onChange={this?.handleDeckListChange}
          className="form-control"
          rows="15"
          required
        >
          {format}
        </textarea>
      </div>
    );
  }

CodePudding user response:

You can use es6 function to return components which exist outside of parent rather than using method,change only this part of code:

1.instead of DeckName(){...}use DeckName =()=>{....} 2.instead of DeckList(){...}use DeckList =()=>{....}

Full modified code:

import React, { Component } from "react";
export class DeckForm extends Component {
  constructor(props) {
    super(props);
    this.state = { deckName: "", deckList: "" };
    // Bind our event handler methods to this class
    this.handleDeckNameChange = this.handleDeckNameChange.bind(this);
    this.handleDeckListChange = this.handleDeckListChange.bind(this);
    this.handleSubmission = this.handleSubmission.bind(this);
  }

  // Event handler method to update the state of the deckName each time a user types into the input form element
  handleDeckNameChange(event) {
    let typed = event.target.value;
    this.setState({ deckName: typed });
  }

  // Event handler method to update the state of the deckList each time a user types into the textarea from element]
  handleDeckListChange(event) {
    let typed = event.target.value;
    console.log(typed);
    this.setState({ deckList: typed });
  }

  // Event handler method to handle validation of deckName and deckList
  handleSubmission(event) {
    console.log(`${this.state.deckName}`);
    console.log(`${this.state.deckList}`);
  }

  render() {
    return (
      <form className="was-validated">
        <this.DeckName />
        <this.DeckList />
        <button type="submit" className="btn-lg btn-warning mt-3">
          Create
        </button>
      </form>
    );
  }

  DeckName = () => {
    return (
      <div className="form-group mb-3">
        <input
          value={this.state.deckName}
          onChange={this.handleDeckNameChange}
          type="text"
          placeholder="Deck name"
          className="form-control"
          required
        />
      </div>
    );
  };

  DeckList = () => {
    let format =
      "EXACT CARD NAME 1\nPot of Greed 3\nChange of Heart 3\nGraceful Charity 3";
    return (
      <div className="form-group">
        <textarea
          value={this.state.deckList}
          onChange={this.handleDeckListChange}
          className="form-control"
          rows="15"
          required
        >
          {format}
        </textarea>
      </div>
    );
  };
}

Live Demo: https://codesandbox.io/s/brave-hill-l0eknx?file=/src/DeckForm.js:0-2091

  • Related