最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - onClick anonymous function with arguments vs onClick(function(arguments)) - Stack Overflow

programmeradmin5浏览0评论

I would like to know why in certain types of events, such as onClick, I have to declare an anonymous function to execute the onClick if my function contains arguments.

Example:

export default function App() {

  const myValue = "MY VALUE";

  
  const handleClick = (anyString) => {
    console.log(anyString);
  };
  

  const anotherClick = () => {
    console.log("It works");
  };

  return (
    <>
      <Button onClick={() => anotherClick()} color="primary">
        Works without arguments <-- Works
      </Button>
      <Button onClick={anotherClick} color="secondary">
        Works without arguments <-- Works
      </Button>
      <Button onClick={() => handleClick(myValue)} color="primary">
        Works with arguments <-- Works
      </Button>
      <Button onClick={handleClick(myValue)} color="secondary">
        Does NOT work with arguments <-- Does NOT work
      </Button>
    </>
  );
}

Question I do not understand why I have to create an anonymous function if the function I want to execute has arguments.

Why do I have to do onClick={() => handleClick(myString)}?

Why onClick={handleClick(myString)} is not enough?

I would like to know why in certain types of events, such as onClick, I have to declare an anonymous function to execute the onClick if my function contains arguments.

Example: https://codesandbox.io/s/suspicious-ramanujan-v998u

export default function App() {

  const myValue = "MY VALUE";

  
  const handleClick = (anyString) => {
    console.log(anyString);
  };
  

  const anotherClick = () => {
    console.log("It works");
  };

  return (
    <>
      <Button onClick={() => anotherClick()} color="primary">
        Works without arguments <-- Works
      </Button>
      <Button onClick={anotherClick} color="secondary">
        Works without arguments <-- Works
      </Button>
      <Button onClick={() => handleClick(myValue)} color="primary">
        Works with arguments <-- Works
      </Button>
      <Button onClick={handleClick(myValue)} color="secondary">
        Does NOT work with arguments <-- Does NOT work
      </Button>
    </>
  );
}

Question I do not understand why I have to create an anonymous function if the function I want to execute has arguments.

Why do I have to do onClick={() => handleClick(myString)}?

Why onClick={handleClick(myString)} is not enough?

Share Improve this question edited Aug 17, 2020 at 17:02 Magofoco asked Aug 17, 2020 at 16:57 MagofocoMagofoco 5,4767 gold badges43 silver badges87 bronze badges 3
  • because you are executing the function and assigning what it returns to the click handler. Did you not see it was called right away? – epascarello Commented Aug 17, 2020 at 16:59
  • 1 onClick={handleClick(myString)} calls the function immediately (during the render) and attempts to assign the returned value to onClick; whereas onClick={() => handleClick(myString) passes a function reference that will then be called on click. – Brian Thompson Commented Aug 17, 2020 at 17:00
  • 1 Also an important note - onClick={anotherClick} is not equivalent to onClick={anotherClick()} (for the same reason as the above ments). The following parenthesis that signal the function should be called is a very important distinction. – Brian Thompson Commented Aug 17, 2020 at 17:02
Add a ment  | 

4 Answers 4

Reset to default 4

onClick accepts a callback i.e. a function that will be called when the button is clicked.

  1. anotherClick is a function so it works, as it's being called properly
  2. () => anotherClick() is equivalent to this
...
const myTempFunction = () => {
  anotherClick();
}
...
onClick={myTempFunction}

Since you're ultimately passing a function to onClick it works

  1. () => handleClick(myValue) same reason as above, and equivalent code is
...
const myTempFunction = () => {
  handleClick(myValue);
}
...
onClick={myTempFunction}
  1. handleClick(myValue), now here you're actually calling the function the you're passing the value that the function returns to onClick, not the function itself, the equivalent code would be
...
const myResult = handleClick(myValue); // This is the result of calling the function
...
onClick={myResult} // myResult isn't a function, it's the return value of handleClick(myValue)

Since you're not actually passing a function to onClick, onClick can't be called and it doesn't work

This is due to design of the syntax extension what we called JSX Template extension. When it es to event Handling inside JSX, it needs a reference to the callback function which is going to trigger after specific event happens.

This is before JSX is converted in to JavaScript Via Babel

  return (
    <div>
      <Button onClick={anotherClick} color="secondary">
        Works without arguments
      </Button>
      <Button onClick={handleClick(myValue)} color="secondary">
        Does NOT work with arguments 
      </Button>
    </div>
  );

This is after the Babel Conversion.

  return React.createElement("div", null, React.createElement(Button, {
          onClick: anotherClick,
          color: "secondary"
        }, "Works without arguments"), 
         React.createElement(Button, {
          onClick: handleClick(myValue),
          color: "secondary"
        }, "Does NOT work with arguments"));

You can clearly see here that second click handler is executing the function directly rather than passing a callback function to React.createElement. Because internally React Element need a callback function to get pass to this function and you are just try to execute that function instead of parsing the reference.

You are supposed to specify a function in onClick={func}. "func" is only referring to a variable.

When saying onClick={func()}, you are adding the return value of func(), rather than specifying function func() { } to be executed, when the event is emitted.

When the button is clicked, the function, specified in onClick={} is executed. This is what you are doing:

let emit = function () { };
button.addEventListener('click', emit());

When the button is clicked, it tries to call undefined as a function, since the function emit() has returned undefined.

In the doc for (Handling Component Events), there is an example

function ActionLink() {
  function handleClick(e) {
    e.preventDefault();
    console.log('The link was clicked.');
  }

  return (
    <a href="#" onClick={handleClick}>
      Click me
    </a>
  );
}

So we could see that every value passed to event handler props (onClick, onFocus,...) must be a method (or you may say function)

Go back to your example, in the first 3, you pass function, so it definitely works. But with the 4th, first to say handleClick is simply a method that return undefined, so when you call onClick={handleClick(myValue)}, it similar to onClick={undefined}, which resulted in nothing happened

const handleClick = (anyString) => {
  console.log(anyString);
};
// ...
<Button onClick={handleClick(myValue)} color="secondary">
  Does NOT work with arguments <-- Does NOT work
</Button>
发布评论

评论列表(0)

  1. 暂无评论