5

I'm in the process of learning React JS, while following an online tutorial. The below code stopped working and gives me an exception "TypeError: Cannot read property 'PreventDefault' of undefined". Can someone please help me understand the reason causing this? Thanks in advance.

const Card = (props)=>{
  return(
        <div style={{margin:'1em'}}>
          <img width ="75" src ={props.avatar_url}/>
          <div style={{display: 'inline-block', marginLeft: 10}}>
             <div style ={{fontSize:'1.25em', fontWeight: 'bold'}}>
               {props.name}
             </div>
             <div>{props.company}</div>
          </div>
        </div>
       );
};

const CardList = (props) => {
    return (
            <div>
                {props.cards.map(card => <Card {...card} />)}
             </div>
           );
       }

class Form extends React.Component {

  handleSubmit = (e) => {
        e.PreventDefault();
        console.log('Event: Form Submit');
  };

  render() {
        return (
        <form onSubmit={this.handleSubmit()}>
        <input type ="text" placeholder ="Github username"/>
        <button type ="submit">Add Card</button>
      </form>
    );
  }
}

class App extends React.Component {

state = {
    cards:  [
        {       name : "Paul O’Shannessy" , avatar_url: "https://avatars1.githubusercontent.com/u/8445?v=4", company: "Facebook"  },
        {       name : "Ben Alpert" , avatar_url: "https://avatars1.githubusercontent.com/u/6820?v=4",company: "Facebook"  },
      ]
}

  render() {
        return(
            <div>
              <Form />
              <CardList cards={this.state.cards} />
            </div>
        );
  }
}

ReactDOM.render(<App />,mountNode)
Cohen
  • 2,375
  • 3
  • 16
  • 35
user2066540
  • 357
  • 2
  • 5
  • 16

4 Answers4

14

Two small problems here. First one, it is not PreventDefault, it is preventDefault. Then here:

<form onSubmit={this.handleSubmit()}>

You are not using a callback function instead, you are invoking the real function. If you don't use a callback, you can't get the e. Also, if you use it like above, it fires in the first render but never fires again with a submit.

<form onSubmit={() => this.handleSubmit()}>

But, you don't need to and shouldn't use it like this. If you use it like this, the callback function will be recreated in every render. Just use the function's reference. You can get e with this, too.

<form onSubmit={this.handleSubmit}>

One last thing, use a key for your Card's map.

{props.cards.map( card => <Card key={card.name} {...card} /> )}

Oh, maybe one last thing :) Use a linter if you don't use it currently.

devserkan
  • 16,870
  • 4
  • 31
  • 47
4

You need to attach just the function object to the onSubmit props, NO NEED to call it as you did onSubmit={this.handleSubmit()}. It should be onSubmit={this.handleSubmit}

Also, it is called preventDefault, not PreventDefault.

const Card = (props) => {
  return (
    <div style={{ margin: '1em' }}>
      <img width="75" src={props.avatar_url} />
      <div style={{ display: 'inline-block', marginLeft: 10 }}>
        <div style={{ fontSize: '1.25em', fontWeight: 'bold' }}>
          {props.name}
        </div>
        <div>{props.company}</div>
      </div>
    </div>
  );
};

const CardList = (props) => {
  return (
    <div>
      {props.cards.map(card => <Card {...card} />)}
    </div>
  );
}

class Form extends React.Component {

  handleSubmit = (e) => {
    e.preventDefault();
    console.log('Event: Form Submit');
  };

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <input type="text" placeholder="Github username" />
        <button type="submit">Add Card</button>
      </form>
    );
  }
}

class App extends React.Component {

  state = {
    cards: [
      { name: "Paul O’Shannessy", avatar_url: "https://avatars1.githubusercontent.com/u/8445?v=4", company: "Facebook" },
      { name: "Ben Alpert", avatar_url: "https://avatars1.githubusercontent.com/u/6820?v=4", company: "Facebook" },
    ]
  }

  render() {
    return (
      <div>
        <Form />
        <CardList cards={this.state.cards} />
      </div>
    );
  }
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
<script crossorigin src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>

<div id='root'></div>
Arup Rakshit
  • 116,827
  • 30
  • 260
  • 317
1

Did you try simple like this:

 <form onSubmit={e => {e.preventDefault();}} >

I hope that helps

StefaDesign
  • 929
  • 10
  • 19
0

In my case, my form component was inside another one (I didn't notice this, because the parent form were also in the parent component). So, when press the submit button, it affects to the parent one.

In conclusion, just add the e.preventDefault() on parent, or remove the form parent.

Dharman
  • 30,962
  • 25
  • 85
  • 135
Carlos Vallejo
  • 3,290
  • 3
  • 9
  • 13