Welcome to the Treehouse Community

The Treehouse Community is a meeting place for developers, designers, and programmers of all backgrounds and skill levels to get support. Collaborate here on code errors or bugs that you need feedback on, or asking for an extra set of eyes on your latest project. Join thousands of Treehouse students and alumni in the community today. (Note: Only Treehouse students can comment or ask questions, but non-students are welcome to browse our conversations.)

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and a supportive community. Start your free trial today.

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

Siddharth Nasare
Siddharth Nasare
15,636 Points

<Home> component shows an empty object in developers tool.

TypeError: Cannot read property 'push' of undefined
Home._this.handleSubmit
C:\Users\Siddharth\Google Drive\My\Web Dev\MyCode\Front-End\React\react-router-4\1-Getting-Started-with-React-Router\3-Introducing-the-Project\course-directory\src\components\Home.js:10
   7 |   let teacherName = this.name.value;
   8 |   let teacherTopic = this.topic.value;
   9 |   let path = `teachers/${teacherTopic}/${teacherName}`;
> 10 |   this.props.history.push(path);
  11 | }
  12 | 
  13 | render() {

Shows above error message while running this code

Home.js

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 Teacher</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;
Featured.js

import React from 'react';

const Featured = ({match}) => {
let name = match.params.name;
let topic = match.params.topic;
  return (
    <div className="main-content">
      <h2>{name}</h2>
      <p>Introducing <strong>{name}</strong>, a teacher who loves teaching courses about <strong>{topic}</strong>!</p>
    </div>
  );
}

export default Featured;
App.js

import React from 'react';
import {
    BrowserRouter,
    Route,
    Switch
} from 'react-router-dom';

// App component
import Header from './Header';
import Home from './Home';
import About from './About';
import Teachers from './Teachers';
import Courses from './Courses';
import NotFound from './NotFound';
import Featured from './Featured';

const App = () => (
    <BrowserRouter>
      <div className="container">
      <Header />
      <Switch>
          <Route exact path="/" render={ () => <Home /> } />
          <Route path="/about" render={ () => <About title="About"/> } />
          <Route exact path="/teachers" render={ () => <Teachers /> } />
            <Route path="/teachers/:topic/:name" render={ () => <Featured />} />
          <Route path="/courses" render={ () => <Courses /> } />
          <Route component = {NotFound} />
         </Switch>
      </div>
  </BrowserRouter>
);

export default App;

Even in the previous section, match property didn't work either.

2 Answers

Your code looks alright. I did noticed that you use render for Home and Teachers when the instructor uses component <Route exact path="/" render={ () => <Home /> } /> - I don't foresee that making a difference as React Router documentation says history/match methods are passed to both component and render ;/ I'd recommend inspecting your Home props, to ensure props.history and props.history.push exist. I suspect the problem lies in App.js. Good Luck, I'm sorry I couldn't be much help.

Siddharth Nasare
Siddharth Nasare
15,636 Points

Thanks @miguelorange for the suggestion. I will try to locate a problem in App.js. Thank you!!!

David Agumya
David Agumya
12,285 Points

I found the problem. When you use render prop instead of component prop then the Home component does not even get the history object passed in.

If you check you console when you use render vs component you will notice that while render produces and empty object. Component actually produces the history, match and location objects.

Now I wonder, doesn't this limit your ability to pass data into components using the render prop, considering component prop does not let you pass data to child components