0

I have a piece of code as below:

for (let i = 0; i <= total; i++)
  leftButtons.push(<Button onClick={() => console.log(i)} key={`leftBtn_${i}`} color="primary">{i + 1}</Button>);

This will cause a compiling error and the error message as "Module parse failed: Unexpected token (36:23) You may need an appropriate loader to handle this file type."

If I remove console.log(i) or change it to do not use i in the onClick, it will pass the compile. I really confuse why I can not use i in the onClick.

Kevin
  • 1,271
  • 9
  • 14
  • What are you trying to achieve – Muhaimin CS Jul 27 '18 at 05:51
  • Hi Muhaimin, thank you for your attention. What I want to achieve is not really important here. I can find a way to go around. But I just do not understand why this code will cause a compiling error. Why I can not use the variable i in the onClick. – Kevin Jul 27 '18 at 05:57
  • Possibly its because you are using arrow functions for which you haven't configured babel. You could refer https://stackoverflow.com/questions/48801984/unexpected-token-in-react-component/48802029#48802029 – Shubham Khatri Jul 27 '18 at 05:58
  • Hi Shubham, thank you for your answer. But I did configure babel and I can use arrow functions just find in other places. If I change it to console.log(2), it will pass the compiling. So, the problem is using the variable i. – Kevin Jul 27 '18 at 05:59
  • Could you make the variable i to be a string in the console.log – Muhaimin CS Jul 27 '18 at 06:06
  • The problem is I can not pass any variable I define in the for loop to onClick no matter what kind of variable is. But I would like to know why. – Kevin Jul 27 '18 at 06:13

3 Answers3

0

Instead of:

onClick={() => console.log(i)}    

Try doing:

onClick={() => console.log(i).bind(this)}   

IMHO, this happens because you are using arrow function syntax and because let is confined within for loop and without bind that console will behave as it belongs to the global/outer scope where your let variable i does not exists.

BlackBeard
  • 10,246
  • 7
  • 52
  • 62
  • Thank you for the answer. But it is not because binding this. I has already found the problem. Please see my post. – Kevin Jul 27 '18 at 06:20
  • It should not relate to binding because the onClick function does not use this. And yes, I tried binding. It does work. But if I change for (let i ...) to for (var i ...), it works just fine. – Kevin Jul 27 '18 at 06:34
  • 1
    @Kevin Yes, that's because `let` is confined within for loop and without `bind` that console will behave as it belongs to the global/outer scope where your let variable i **does not** exists. – BlackBeard Jul 27 '18 at 06:37
0

Got it. The let keyword just allows the variable i live in the for block. However, the onClick function will be used out of the for scope, which will cause the variable i does not exist at that time. However, the compiling error message is too wired.

Kevin
  • 1,271
  • 9
  • 14
0

As I noticed you used leftButtons variables to push your buttons which is wrong approach. You already have total and you wanna print buttons for every single record.

You can easily accomplish that in jsx.

{
 for (let i = 0; i <= total; i++){
  <Button onClick={() => console.log(i)} key={`leftBtn_${i}`} color="primary">{i + 1}</Button>;
 }
} 
Ruhul Amin
  • 1,751
  • 15
  • 18
  • 1
    Hi Ruhul, thank you for your answer. However, the total is just a number instead of an array. So, map will not work for this case. – Kevin Jul 27 '18 at 23:00
  • @Kevin, you are right but did it solve your problem? – Ruhul Amin Jul 30 '18 at 09:50
  • Ruhul, thank you for asking. I solved this by using the event.target.innerText to get the number I want. Finding this solution actually did not cost me too much time. But figure out why my original code does not work is the hard part. I just feel uncomfortable if I get some errors and I cannot understand. :) – Kevin Jul 31 '18 at 06:29