Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

JavaScript React Router 4 Basics Going Further with Routing Navigating Routes Programmatically

Why handleSubmit is not defined?

I've looked my code over dozens of times and compared mine with Guil's, but I can't seem to figure out what it's missing. My handleSubmit function keeps coming back as undefined.

Here's my code:

import React, { Component } from 'react';

class Home extends Component {

  handleSubmit = (e) => {
    e.preventDefault();
    let teacherName = this.name.value;
    let teacherTopic = this.topic.value;
    let path = `teachers/${teacherTopic}/${teacherName}`;
    this.props.history.push(path);
  }
  render() {
    return (
      <div className="main-content home">
        <h2>Front End Course Directory</h2>
        <p>This fun directory is a project for the <em>React Router Basics</em> course on Treehouse.</p>
        <p>Learn front end web development and much more! This simple directory app offers a preview of our course library. Choose from many hours of content, from HTML to CSS to JavaScript. Learn to code and get the skills you need to launch a new career in front end web development.</p>
        <p>We have thousands of videos created by expert teachers on web design and front end development. Our library is continually refreshed with the latest on web technology so you will never fall behind.</p>
        <hr />
        <h3> Featured Teachers </h3>
        <form onSubmit={this.handleSubmit}>
          <input type="text" placeholder="Name" ref={(input)=> this.name= input}/>
          <input type="text" placeholder="Topic" ref={(input)=> this.topic= input}/>
          <button type="submit">Go!</button>
        </form>
      </div>
    );
  }
}

export default Home;

3 Answers

Ari Misha
Ari Misha
19,323 Points

Hello there! It's happening probably 'coz you didn't bind the function handleSubmit() with the current context. React Classes are evaluated by Babel and JavaScript in strict mode (you must have read 'use strict' in many code examples). In strict mode in JavaScript, the context of the current method gets lost, whereas, in functional components and Arrow functions, every variable or const or function gets bind to the local scope, that's why Arrow Functions are recommended in javascript. Whereas, without using strict mode, if the current context can't be found, the context gets bound to the Global scope, i.e., either Window or Document.

Now, in React, handlers binding can be done in two ways, either in the constructor(recommended) or bind the method where you attach the current method.

...

class Home extends Component{
   constructor(props) {
      super(props);
      this.handleSubmit = this.handleSubmit.bind(this);
   }

  handleSubmit() {}

  render() {
    return (
      ...
      <form onSubmit={this.handleSubmit}> ..... </form>
    );
  }
}
....

OR

...

class Home extends Component{
   constructor(props) {
      super(props);
   }

  handleSubmit() {}

  render() {
    return (
      ...
      <form onSubmit={this.handleSubmit.bind(this)}> ..... </form>
    );
  }
}
....

OR (in case of functional components)

const Home = props => (
    ...
    <form onSubmit={this.handleSubmit}> ..... </form>
    ...
);

I hope it helped!

~ Ari

Thanks for the response. I still am at a loss of why this exact code works for his example with the same set up, but not mine.

Ari Misha
Ari Misha
19,323 Points

Stephen Powers Its happenin' 'coz you didn't the handleSubmit() handler to the current Object.

Rich Donnellan
MOD
Rich Donnellan
Treehouse Moderator 27,708 Points

I ran into the same problem and updating all of the outdated dependencies in the package.json sorted things out.

Mike Hatch
Mike Hatch
14,940 Points

Hi Rich,

Would you mind sharing how you went about that? I deleted the node_modules folder and then ran npm install to reinstall them. When that didn't work I tried doing what you did by entering npm install -g npm-check-updates. Still gives me the error: Line 5: 'handleSubmit' is not defined no-undef

I'm not sure I understand Ari's fix because we've already defined handleSubmit as a function on Line 1 below:

  handleSubmit = (e) => {
      e.preventDefault() 
      let teacherName = this.name.value
      let teacherTopic = this.topic.value
      let path = `teachers/${teacherTopic}/${teacherName}`
      this.props.history.push(path)
  }
Britton Kitchell
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Britton Kitchell
Full Stack JavaScript Techdegree Graduate 14,927 Points

I am having the same issue as Mike 3+ years later... I tried both of Ari's suggestions as well as updating the dependencies, but no luck. If I use the "course_directory_final" files, it works fine.

Has anyone determined what could be causing this?

Jamie Reardon
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Jamie Reardon
Treehouse Project Reviewer

Seems to be working fine for me. Could someone having issues please share their project? This requires a more in depth look ideally to understand.