1

I'm learning React.Js. I'm trying to attach an event to write something in the console, however i cant get my function to trigger. Does anyone know how i would attach an onClick event to a react div? I apologise if this is a basic question but ive tried several different methods and none of them are working.

I have tried the two ways of triggering the function shown below but neither is working.

So, Ive realised that the reason that the events were not working was because I was rendering server side. If i render on the client then the event triggers. Does anyone know how to make it trigger if i have initially rendered on the server?

class Individual extends React.Component {
    handleClick = () => {
        alert("GREAT");
    }
    render() {
        const indDiv = {
            margin: '5px',
            width: '100px',
            height: '120px',
            cursor: 'pointer',
            border: '5px solid pink',
            color: 'blue',
            float: 'left'
        };

        return (
            <div>
                <div onClick={this.handleClick.bind(this)}>
                    Alert 1
                </div>
                <div onClick={() => this.handleClick}>
                    Alert 2
                </div>
                <div style={indDiv}>
                    {this.props.num}. {this.props.name}.
                </div>
            </div>
        );
    }
}

Thank you to everyone that contributed to this. After everything i found that because i had initially created this as a server rendered piece, I had to attach the events after the page had rendered. I was using ReactJS.Net and had to initialize it seperately using hydrate.

Christopher Vickers
  • 1,773
  • 1
  • 14
  • 18
  • Are you using create-react-app and using the latest version of React? If so, remove `this` from inside the `onClick` – ProEvilz Jan 07 '19 at 02:32
  • Either remove the `this` or bind the click handler to the class in the constructor. – Ben Jan 07 '19 at 02:35
  • if you declare thr function like above code, you dont need to bind it. you just write like this. `onClick={this.handleClick}` OR `onClick={()=>{this.handleClick()}}` – kyun Jan 07 '19 at 02:49

6 Answers6

2

Both the ways of calling handler function is incorrect in your code.

In your code handleClick is an arrow function hence manual binding is not required.

If it is not an arrow function then the manual binding should be done always in constructor only. Never do binding anywhere else like you did in render.

When you use onClick={() => this.handleClick} this is wrong. It should be onClick={()=> this.handleClick()}. If no Paranthesis then this is correct onClick={this.handleClick}

So change

    <div onClick={this.handleClick.bind(this)}>
                Alert 1
            </div>
            <div onClick={() => this.handleClick}>
                Alert 2
            </div>

To

    <div onClick={()=> this.handleClick()}>
                Alert 1
            </div>
            <div onClick={() => this.handleClick()}>
                Alert 2
            </div>

The reason you should not do binding anywhere else in the component except constructor because for eg you did binding directly in render so what happens in this case is it creates a new function in webpack bundle file every time the component renders and re renders again hence bundle file grows large. Hence it is recommended to bind it only in constructor

Hemadri Dasari
  • 32,666
  • 37
  • 119
  • 162
  • 1
    Thanks. This was the correct solution, however I have realised that the events only trigger when they are rendered on the client. Rendering on the server prevents then functioning. Do you have any idea how to make that work? – Christopher Vickers Jan 07 '19 at 03:03
  • Sorry! I have no idea about server side rendering. Please check this thread may be helpful https://stackoverflow.com/questions/36233309/react-js-serverside-rendering-and-event-handlers – Hemadri Dasari Jan 07 '19 at 03:12
1

You need to declare the handler method after the render method. Here is a basic implementing of your code in jsfiddle.

https://jsfiddle.net/ufyxwv8p/

class Individual extends React.Component {
    render() {
        const indDiv = {
            margin: '5px',
            width: '100px',
            height: '120px',
            cursor: 'pointer',
            border: '5px solid pink',
            color: 'blue',
            float: 'left'
        };

        return (
            <div>
                <div onClick={this.handleClick}>
                    Click to show in console
                </div>
                <div style={indDiv}>
                    {this.props.num}. {this.props.name}.
                </div>
            </div>
        );
    }
    handleClick = () => {
        console.log('this is:', this);
    }
}

ReactDOM.render(<Individual/>,document.getElementById("app"))
  • The order does not make any difference in this situation. In fact many standard ESLint configurations will treat this as an error/warning if render is not the very last method in the class. – Alexander Staroselsky Jan 07 '19 at 03:01
  • but i don't think, i changed anything else to make it work. I also thought that javascript support hoisting, but it worked as no binding problem is there, because arrow functions don't need this binding. – Syed Sadiq ali Jan 07 '19 at 03:31
  • Technically, you removed the line regarding Alert 2 onClick handler that was in the question, which was the cause of the issue, described in other answers. As you removed the problematic event handler, the code worked. Order of the methods wasn’t the reason. – Alexander Staroselsky Jan 07 '19 at 04:24
1

here try like this the way you are defining your handleclick function is wrong i have edited your code online on sandbox to make it work. call function the way you are calling on Alert 1 than define function the way I have uploaded an image

Link of codesandbox of your code check that

Check this image of that code if you dont have time to go through whole code

0

You have to use bind

onClick={this.handleClick.bind(this)}

or use arrow function

onClick={()=>this.handleClick()}
31113
  • 399
  • 4
  • 18
0

The click handler on Alert 1 is already working. It's not necessary to bind when you use a the () => {} class properties syntax.

Your click handler on Alert 2 isn't working because you've written an inline arrow function which returns another function. You need to call it, like () => this.handleClick().

Here is a working snippet of your code.

class Individual extends React.Component {
  handleClick = () => {
    alert("GREAT");
  };
  render() {
    const indDiv = {
      margin: "5px",
      width: "100px",
      height: "120px",
      cursor: "pointer",
      border: "5px solid pink",
      color: "blue",
      float: "left"
    };

    return (
      <div>
        <div onClick={this.handleClick}>Alert 1</div>
        <div onClick={() => this.handleClick()}>Alert 2</div>
        <div style={indDiv}>
          {this.props.num}. {this.props.name}.
        </div>
      </div>
    );
  }
}

ReactDOM.render(<Individual />, document.getElementById("app"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

<div id="app"></div>
maazadeeb
  • 5,922
  • 2
  • 27
  • 40
0
class Individual extends React.Component {
  handleClick = () => {
    alert("GREAT");
  };
  render() {
    const indDiv = {
      margin: "5px",
      width: "100px",
      height: "120px",
      cursor: "pointer",
      border: "5px solid pink",
      color: "blue",
      float: "left"
    };

    return (
      <div>
        <div onClick={this.handleClick}>Alert 1</div>
        <div onClick={this.handleClick}>Alert 2</div>
        <div style={indDiv}>
          {this.props.num}. {this.props.name}.
        </div>
      </div>
    );
  }
}

ReactDOM.render(<Individual />, document.getElementById("app"));
vinoth s
  • 178
  • 6