React event handler works without bind()jQuery Event Keypress: Which key was pressed?How to debug JavaScript / jQuery event bindings with Firebug or similar tools?Understanding events and event handlers in C#Context in Facebook's React JS frameworkLoop inside React JSXProgrammatically navigate using react routermore information on React lifecycle methodsInvariant Violation: Objects are not valid as a React childReact/Redux: modified state is not updated in viewHow get value datapicker in react toobox custom?

Story that includes a description: "Two concentric circles, intersecting at three points"

Is "stainless" a bulk or a surface property of stainless steel?

What animal has fat with the highest energy density?

What can I do to keep a threaded bolt from falling out of it’s slot

Unsolved Problems (Not Independent of ZFC) due to Lack of Computational Power

Has there ever been a truly bilingual country prior to the contemporary period?

Multicolumn in table not centered

"Silverware", "Tableware", and "Dishes"

Why should someone be willing to write a strong recommendation even if that means losing a undergraduate from their lab?

Is there a commercial liquid with refractive index greater than n=2?

How could China have extradited people for political reason under the extradition law it wanted to pass in Hong Kong?

Are there categories whose internal hom is somewhat 'exotic'?

How to avoid using System.String with Rfc2898DeriveBytes in C#

Did Wernher von Braun really have a "Saturn V painted as the V2"?

Is it allowable to use an organization's name to publish a paper in a conference, even after I graduate from it?

Could sidesticks be linked?

How do slats reduce stall speed?

Chess software to analyze games

Nuclear decay triggers

What is "super" in superphosphate?

How do neutron star binaries form?

How to translate 脑袋短路 into English?

Syncing bitcoin node with multiple cores

Would it be illegal for Facebook to actively promote a political agenda?



React event handler works without bind()


jQuery Event Keypress: Which key was pressed?How to debug JavaScript / jQuery event bindings with Firebug or similar tools?Understanding events and event handlers in C#Context in Facebook's React JS frameworkLoop inside React JSXProgrammatically navigate using react routermore information on React lifecycle methodsInvariant Violation: Objects are not valid as a React childReact/Redux: modified state is not updated in viewHow get value datapicker in react toobox custom?






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;








1















I'm working through a react tutorial and the instructor is showing that the event handler in this code won't work, because this() is accessing the outer environment. But I get no error. Can someone explain it to me?



import React, Component from "react";

class Counter extends Component
state =
count: 0,
;

handleIncrement()
console.log(this.state);
console.log(this.props);


render()
return (
<div>
<button onClick=this.handleIncrement()>
Increment
</button>
</div>
);



export default Counter;









share|improve this question





















  • 4





    Welcome to Stack Overflow Benedikt! You are invoking this.handleIncrement directly on render. You want to give onClick a function that should be invoked when the event occurs instead, e.g () => this.handleIncrement()

    – Tholle
    Mar 27 at 14:06











  • But why it works for me event with non-arrow function?

    – Benedikt Hofírek
    Mar 27 at 14:18






  • 2





    It doesn't. You are calling the function with the () directly on render which will give you the correct this, but that's not what you want to do.

    – Tholle
    Mar 27 at 14:21











  • I'm sorry, but I'm talking about this() in console.log(this.state).

    – Benedikt Hofírek
    Mar 27 at 14:24







  • 1





    Please read my previous comments again. You are invoking this.handleIncrement directly on render by writing this.handleIncrement(). This is not what you want to do.

    – Tholle
    Mar 27 at 14:25

















1















I'm working through a react tutorial and the instructor is showing that the event handler in this code won't work, because this() is accessing the outer environment. But I get no error. Can someone explain it to me?



import React, Component from "react";

class Counter extends Component
state =
count: 0,
;

handleIncrement()
console.log(this.state);
console.log(this.props);


render()
return (
<div>
<button onClick=this.handleIncrement()>
Increment
</button>
</div>
);



export default Counter;









share|improve this question





















  • 4





    Welcome to Stack Overflow Benedikt! You are invoking this.handleIncrement directly on render. You want to give onClick a function that should be invoked when the event occurs instead, e.g () => this.handleIncrement()

    – Tholle
    Mar 27 at 14:06











  • But why it works for me event with non-arrow function?

    – Benedikt Hofírek
    Mar 27 at 14:18






  • 2





    It doesn't. You are calling the function with the () directly on render which will give you the correct this, but that's not what you want to do.

    – Tholle
    Mar 27 at 14:21











  • I'm sorry, but I'm talking about this() in console.log(this.state).

    – Benedikt Hofírek
    Mar 27 at 14:24







  • 1





    Please read my previous comments again. You are invoking this.handleIncrement directly on render by writing this.handleIncrement(). This is not what you want to do.

    – Tholle
    Mar 27 at 14:25













1












1








1








I'm working through a react tutorial and the instructor is showing that the event handler in this code won't work, because this() is accessing the outer environment. But I get no error. Can someone explain it to me?



import React, Component from "react";

class Counter extends Component
state =
count: 0,
;

handleIncrement()
console.log(this.state);
console.log(this.props);


render()
return (
<div>
<button onClick=this.handleIncrement()>
Increment
</button>
</div>
);



export default Counter;









share|improve this question
















I'm working through a react tutorial and the instructor is showing that the event handler in this code won't work, because this() is accessing the outer environment. But I get no error. Can someone explain it to me?



import React, Component from "react";

class Counter extends Component
state =
count: 0,
;

handleIncrement()
console.log(this.state);
console.log(this.props);


render()
return (
<div>
<button onClick=this.handleIncrement()>
Increment
</button>
</div>
);



export default Counter;






reactjs event-handling bind






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Mar 27 at 14:41









ThatBrianDude

1,3836 silver badges30 bronze badges




1,3836 silver badges30 bronze badges










asked Mar 27 at 14:04









Benedikt HofírekBenedikt Hofírek

61 bronze badge




61 bronze badge










  • 4





    Welcome to Stack Overflow Benedikt! You are invoking this.handleIncrement directly on render. You want to give onClick a function that should be invoked when the event occurs instead, e.g () => this.handleIncrement()

    – Tholle
    Mar 27 at 14:06











  • But why it works for me event with non-arrow function?

    – Benedikt Hofírek
    Mar 27 at 14:18






  • 2





    It doesn't. You are calling the function with the () directly on render which will give you the correct this, but that's not what you want to do.

    – Tholle
    Mar 27 at 14:21











  • I'm sorry, but I'm talking about this() in console.log(this.state).

    – Benedikt Hofírek
    Mar 27 at 14:24







  • 1





    Please read my previous comments again. You are invoking this.handleIncrement directly on render by writing this.handleIncrement(). This is not what you want to do.

    – Tholle
    Mar 27 at 14:25












  • 4





    Welcome to Stack Overflow Benedikt! You are invoking this.handleIncrement directly on render. You want to give onClick a function that should be invoked when the event occurs instead, e.g () => this.handleIncrement()

    – Tholle
    Mar 27 at 14:06











  • But why it works for me event with non-arrow function?

    – Benedikt Hofírek
    Mar 27 at 14:18






  • 2





    It doesn't. You are calling the function with the () directly on render which will give you the correct this, but that's not what you want to do.

    – Tholle
    Mar 27 at 14:21











  • I'm sorry, but I'm talking about this() in console.log(this.state).

    – Benedikt Hofírek
    Mar 27 at 14:24







  • 1





    Please read my previous comments again. You are invoking this.handleIncrement directly on render by writing this.handleIncrement(). This is not what you want to do.

    – Tholle
    Mar 27 at 14:25







4




4





Welcome to Stack Overflow Benedikt! You are invoking this.handleIncrement directly on render. You want to give onClick a function that should be invoked when the event occurs instead, e.g () => this.handleIncrement()

– Tholle
Mar 27 at 14:06





Welcome to Stack Overflow Benedikt! You are invoking this.handleIncrement directly on render. You want to give onClick a function that should be invoked when the event occurs instead, e.g () => this.handleIncrement()

– Tholle
Mar 27 at 14:06













But why it works for me event with non-arrow function?

– Benedikt Hofírek
Mar 27 at 14:18





But why it works for me event with non-arrow function?

– Benedikt Hofírek
Mar 27 at 14:18




2




2





It doesn't. You are calling the function with the () directly on render which will give you the correct this, but that's not what you want to do.

– Tholle
Mar 27 at 14:21





It doesn't. You are calling the function with the () directly on render which will give you the correct this, but that's not what you want to do.

– Tholle
Mar 27 at 14:21













I'm sorry, but I'm talking about this() in console.log(this.state).

– Benedikt Hofírek
Mar 27 at 14:24






I'm sorry, but I'm talking about this() in console.log(this.state).

– Benedikt Hofírek
Mar 27 at 14:24





1




1





Please read my previous comments again. You are invoking this.handleIncrement directly on render by writing this.handleIncrement(). This is not what you want to do.

– Tholle
Mar 27 at 14:25





Please read my previous comments again. You are invoking this.handleIncrement directly on render by writing this.handleIncrement(). This is not what you want to do.

– Tholle
Mar 27 at 14:25












2 Answers
2






active

oldest

votes


















0














Any function called directly from render method will get the container object as this
But when we assign a function to onClick event, we don't want to call that function immediately... so we assign it like this



<button onClick=this.handleIncrement>


(only the function name without () at the end) ... and this says to call the function when the button is clicked.



But when you click the button the function will not be called from the render method anymore so the this reference will be changed and produce an error.



In your case, you added the () to your this.handleIncrement function invoking it immediately... so it's not causing any problem but it will give you wrong results in almost all cases since it won't get called on click but it will get called with each render.



Since your simple code gets rendered only on button click it's probably correcting the problem. Add a second button and it will give wrong result or the UI will freeze.



The correct way is to remove the () after this.handleIncreament and bind the function inside constructor ... this.handleIncreament = this.handleIncreament.bind(this)






share|improve this answer
































    0














    As Afzal Hossain says, you're invoking this.handleIncrement() when the element renders rather than when the button is clicked.



    You need to provide the function handle itself to onClick, and bind() it to the correct context when it is constructed, so that this always accesses the instance of Counter within handleIncrement().



    Here is a working implementation of the suggestions made in his answer:






    const Component = React;

    class Counter extends Component
    state = count: 0 ;
    handleIncrement = this.handleIncrement.bind(this);

    handleIncrement ()
    const count = this.state;
    this.setState( count: count + 1 );


    render ()
    return <label>
    <div>Count this.state.count</div>
    <button onClick=this.handleIncrement>Increment</button>
    </label>;



    ReactDOM.render(<Counter/>, document.querySelector('main'));

    <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>

    <main/>








    share|improve this answer



























      Your Answer






      StackExchange.ifUsing("editor", function ()
      StackExchange.using("externalEditor", function ()
      StackExchange.using("snippets", function ()
      StackExchange.snippets.init();
      );
      );
      , "code-snippets");

      StackExchange.ready(function()
      var channelOptions =
      tags: "".split(" "),
      id: "1"
      ;
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function()
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled)
      StackExchange.using("snippets", function()
      createEditor();
      );

      else
      createEditor();

      );

      function createEditor()
      StackExchange.prepareEditor(
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader:
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      ,
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      );



      );













      draft saved

      draft discarded


















      StackExchange.ready(
      function ()
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55379187%2freact-event-handler-works-without-bind%23new-answer', 'question_page');

      );

      Post as a guest















      Required, but never shown

























      2 Answers
      2






      active

      oldest

      votes








      2 Answers
      2






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      0














      Any function called directly from render method will get the container object as this
      But when we assign a function to onClick event, we don't want to call that function immediately... so we assign it like this



      <button onClick=this.handleIncrement>


      (only the function name without () at the end) ... and this says to call the function when the button is clicked.



      But when you click the button the function will not be called from the render method anymore so the this reference will be changed and produce an error.



      In your case, you added the () to your this.handleIncrement function invoking it immediately... so it's not causing any problem but it will give you wrong results in almost all cases since it won't get called on click but it will get called with each render.



      Since your simple code gets rendered only on button click it's probably correcting the problem. Add a second button and it will give wrong result or the UI will freeze.



      The correct way is to remove the () after this.handleIncreament and bind the function inside constructor ... this.handleIncreament = this.handleIncreament.bind(this)






      share|improve this answer





























        0














        Any function called directly from render method will get the container object as this
        But when we assign a function to onClick event, we don't want to call that function immediately... so we assign it like this



        <button onClick=this.handleIncrement>


        (only the function name without () at the end) ... and this says to call the function when the button is clicked.



        But when you click the button the function will not be called from the render method anymore so the this reference will be changed and produce an error.



        In your case, you added the () to your this.handleIncrement function invoking it immediately... so it's not causing any problem but it will give you wrong results in almost all cases since it won't get called on click but it will get called with each render.



        Since your simple code gets rendered only on button click it's probably correcting the problem. Add a second button and it will give wrong result or the UI will freeze.



        The correct way is to remove the () after this.handleIncreament and bind the function inside constructor ... this.handleIncreament = this.handleIncreament.bind(this)






        share|improve this answer



























          0












          0








          0







          Any function called directly from render method will get the container object as this
          But when we assign a function to onClick event, we don't want to call that function immediately... so we assign it like this



          <button onClick=this.handleIncrement>


          (only the function name without () at the end) ... and this says to call the function when the button is clicked.



          But when you click the button the function will not be called from the render method anymore so the this reference will be changed and produce an error.



          In your case, you added the () to your this.handleIncrement function invoking it immediately... so it's not causing any problem but it will give you wrong results in almost all cases since it won't get called on click but it will get called with each render.



          Since your simple code gets rendered only on button click it's probably correcting the problem. Add a second button and it will give wrong result or the UI will freeze.



          The correct way is to remove the () after this.handleIncreament and bind the function inside constructor ... this.handleIncreament = this.handleIncreament.bind(this)






          share|improve this answer













          Any function called directly from render method will get the container object as this
          But when we assign a function to onClick event, we don't want to call that function immediately... so we assign it like this



          <button onClick=this.handleIncrement>


          (only the function name without () at the end) ... and this says to call the function when the button is clicked.



          But when you click the button the function will not be called from the render method anymore so the this reference will be changed and produce an error.



          In your case, you added the () to your this.handleIncrement function invoking it immediately... so it's not causing any problem but it will give you wrong results in almost all cases since it won't get called on click but it will get called with each render.



          Since your simple code gets rendered only on button click it's probably correcting the problem. Add a second button and it will give wrong result or the UI will freeze.



          The correct way is to remove the () after this.handleIncreament and bind the function inside constructor ... this.handleIncreament = this.handleIncreament.bind(this)







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Mar 27 at 14:51









          Afzal HossainAfzal Hossain

          1,85014 silver badges11 bronze badges




          1,85014 silver badges11 bronze badges


























              0














              As Afzal Hossain says, you're invoking this.handleIncrement() when the element renders rather than when the button is clicked.



              You need to provide the function handle itself to onClick, and bind() it to the correct context when it is constructed, so that this always accesses the instance of Counter within handleIncrement().



              Here is a working implementation of the suggestions made in his answer:






              const Component = React;

              class Counter extends Component
              state = count: 0 ;
              handleIncrement = this.handleIncrement.bind(this);

              handleIncrement ()
              const count = this.state;
              this.setState( count: count + 1 );


              render ()
              return <label>
              <div>Count this.state.count</div>
              <button onClick=this.handleIncrement>Increment</button>
              </label>;



              ReactDOM.render(<Counter/>, document.querySelector('main'));

              <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>

              <main/>








              share|improve this answer





























                0














                As Afzal Hossain says, you're invoking this.handleIncrement() when the element renders rather than when the button is clicked.



                You need to provide the function handle itself to onClick, and bind() it to the correct context when it is constructed, so that this always accesses the instance of Counter within handleIncrement().



                Here is a working implementation of the suggestions made in his answer:






                const Component = React;

                class Counter extends Component
                state = count: 0 ;
                handleIncrement = this.handleIncrement.bind(this);

                handleIncrement ()
                const count = this.state;
                this.setState( count: count + 1 );


                render ()
                return <label>
                <div>Count this.state.count</div>
                <button onClick=this.handleIncrement>Increment</button>
                </label>;



                ReactDOM.render(<Counter/>, document.querySelector('main'));

                <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>

                <main/>








                share|improve this answer



























                  0












                  0








                  0







                  As Afzal Hossain says, you're invoking this.handleIncrement() when the element renders rather than when the button is clicked.



                  You need to provide the function handle itself to onClick, and bind() it to the correct context when it is constructed, so that this always accesses the instance of Counter within handleIncrement().



                  Here is a working implementation of the suggestions made in his answer:






                  const Component = React;

                  class Counter extends Component
                  state = count: 0 ;
                  handleIncrement = this.handleIncrement.bind(this);

                  handleIncrement ()
                  const count = this.state;
                  this.setState( count: count + 1 );


                  render ()
                  return <label>
                  <div>Count this.state.count</div>
                  <button onClick=this.handleIncrement>Increment</button>
                  </label>;



                  ReactDOM.render(<Counter/>, document.querySelector('main'));

                  <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>

                  <main/>








                  share|improve this answer













                  As Afzal Hossain says, you're invoking this.handleIncrement() when the element renders rather than when the button is clicked.



                  You need to provide the function handle itself to onClick, and bind() it to the correct context when it is constructed, so that this always accesses the instance of Counter within handleIncrement().



                  Here is a working implementation of the suggestions made in his answer:






                  const Component = React;

                  class Counter extends Component
                  state = count: 0 ;
                  handleIncrement = this.handleIncrement.bind(this);

                  handleIncrement ()
                  const count = this.state;
                  this.setState( count: count + 1 );


                  render ()
                  return <label>
                  <div>Count this.state.count</div>
                  <button onClick=this.handleIncrement>Increment</button>
                  </label>;



                  ReactDOM.render(<Counter/>, document.querySelector('main'));

                  <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>

                  <main/>








                  const Component = React;

                  class Counter extends Component
                  state = count: 0 ;
                  handleIncrement = this.handleIncrement.bind(this);

                  handleIncrement ()
                  const count = this.state;
                  this.setState( count: count + 1 );


                  render ()
                  return <label>
                  <div>Count this.state.count</div>
                  <button onClick=this.handleIncrement>Increment</button>
                  </label>;



                  ReactDOM.render(<Counter/>, document.querySelector('main'));

                  <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>

                  <main/>





                  const Component = React;

                  class Counter extends Component
                  state = count: 0 ;
                  handleIncrement = this.handleIncrement.bind(this);

                  handleIncrement ()
                  const count = this.state;
                  this.setState( count: count + 1 );


                  render ()
                  return <label>
                  <div>Count this.state.count</div>
                  <button onClick=this.handleIncrement>Increment</button>
                  </label>;



                  ReactDOM.render(<Counter/>, document.querySelector('main'));

                  <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>

                  <main/>






                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Mar 27 at 15:40









                  Patrick RobertsPatrick Roberts

                  24.2k3 gold badges41 silver badges82 bronze badges




                  24.2k3 gold badges41 silver badges82 bronze badges






























                      draft saved

                      draft discarded
















































                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid


                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.

                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function ()
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55379187%2freact-event-handler-works-without-bind%23new-answer', 'question_page');

                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      SQL error code 1064 with creating Laravel foreign keysForeign key constraints: When to use ON UPDATE and ON DELETEDropping column with foreign key Laravel error: General error: 1025 Error on renameLaravel SQL Can't create tableLaravel Migration foreign key errorLaravel php artisan migrate:refresh giving a syntax errorSQLSTATE[42S01]: Base table or view already exists or Base table or view already exists: 1050 Tableerror in migrating laravel file to xampp serverSyntax error or access violation: 1064:syntax to use near 'unsigned not null, modelName varchar(191) not null, title varchar(191) not nLaravel cannot create new table field in mysqlLaravel 5.7:Last migration creates table but is not registered in the migration table

                      용인 삼성생명 블루밍스 목차 통계 역대 감독 선수단 응원단 경기장 같이 보기 외부 링크 둘러보기 메뉴samsungblueminx.comeh선수 명단용인 삼성생명 블루밍스용인 삼성생명 블루밍스ehsamsungblueminx.comeheheheh

                      155 수학 과학 기타 둘러보기 메뉴eh추가해eh문서를 완성해