11

Trying to do a simple onClick event/function, in ReactJS.

When the button is clicked, I want to run a function called "onClick", but I get this error in console:

app.js:62 Uncaught TypeError: Cannot read property 'preventDefault' of undefined

Have googled, but not sure what I'm going wrong. I've looked at ReactJs documentation and this looks correct, but obviously not. Here's my code:

import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter} from 'react-router-dom';
import axios from 'axios';

import Navbar from './components/Navbar';
import Header from './components/Header';
import GiphyButton from './components/GiphyButton';
import './assets/sass/main.scss';

class App extends React.Component {

  constructor() {
    super();

    this.state = {
      giphy: []
    };

    this.handleClick = this.handleClick.bind(this);
  }

  handleClick(e) {
    e.preventDefault();

    console.log('giffy button clicked');
    axios.get('http://api.giphy.com/v1/gifs/search?q=otters&api_key=<API KEY>')

      .then(res => {
        this.setState({ giphy: res.data });
        console.log(res.data);
      });
  }

  render() {
    return (
      <BrowserRouter>
        <main>
          <Navbar />
          <Header />
          <GiphyButton onClick={this.handleClick()}/>
        </main>
      </BrowserRouter>
    );
  }
}

ReactDOM.render(
  <App />,
  document.getElementById('root')
);

GiphyButton is a component, which is literally, just JSX for a . No other functions running here:

import React from 'react';

const GiphyButton = () => (

  <section>
    <button>See more otters</button>
  </section>
);

export default GiphyButton;

Thank you.

Vivek
  • 1,465
  • 14
  • 29
Reena Verma
  • 1,617
  • 2
  • 20
  • 47

5 Answers5

4

You should bind this event to "handleClick()" function. As follows,

<GiphyButton onClick={this.handleClick.bind(this)}/>
Sashini Hettiarachchi
  • 1,630
  • 2
  • 10
  • 21
  • 1
    It's not generally recommended to bind ```this``` to functions here. It's better to use arrow functions which already have the correct ```this``` in scope or do what you have here in the constructor. https://medium.freecodecamp.org/react-binding-patterns-5-approaches-for-handling-this-92c651b5af56 – Jonathan Rys Nov 03 '18 at 14:27
3

You should just pass function -handleClick and not call it

render() {
    return (
      <BrowserRouter>
        <main>
          <Navbar />
          <Header />
          <GiphyButton handleClick={this.handleClick}/>
        </main>
      </BrowserRouter>
    );
  }

That was preventing event object to be passed causing undefined error.

Change code for GiphyButton with following to pass onclick method -

import React from 'react';

const GiphyButton = (props) => (

  <section>
    <button onClick={props.handleClick}>See more otters</button>
  </section>
);

export default GiphyButton;
Vivek
  • 1,465
  • 14
  • 29
1

Not the answer to my question, but I ended up changing the function to handleSubmit and passing this into a form, which my button sits in. This worked.

Reena Verma
  • 1,617
  • 2
  • 20
  • 47
1

inside the onclick function you have pass event as you calling it. Like ,

onClick={(e)=>this.handleClick(e)}

  • 1
    Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Aug 26 '22 at 16:25
0

the solution of Vivek is correct. the reason why it seems not to run might be your missing error handling. check the url (maybe something wrong with api key?) and try catching axios errors. take a look here:

code example

ugrpla
  • 403
  • 3
  • 11
  • Ok, so I've tried catching the errors and nothing console logs. the button just doesn't seem to run the function at all. I know the approach is correct, but I'm not sure what else is running, other than the original error I was getting... – Reena Verma Jun 23 '18 at 21:42
  • can you post your current code? what is different from the code example that i sent? – ugrpla Jun 23 '18 at 23:39
  • Hi @ugrpla - it's exactly as above. However my button jsx, doesn't sit in the same file. It sits in a seperate component called "GiphyButton". You can see I'm calling it here: import GiphyButton from './components/GiphyButton'; – Reena Verma Jun 24 '18 at 16:04
  • Hi @ReenaVerma - if it's exactly like above, then your button component in GiphyButton has no onClick at all. Pass the clickHandler as property down to your GiphyButton, and call it with `` – ugrpla Jun 25 '18 at 06:55