1

Executing this following piece of code:

function Events (props){
  const clickHandler = console.log;

  return (<button onClick={clickHandler}> Make an event </button>);
}

ReactDOM.render(<Events />, mountNode);

I get this error: Converting circular structure to JSON at JSON.stringify (<anonymous>)

The code is from a pluralsight ReactJS course and when the guy who is presenting the course executes the code, he gets the event triggering object printed in the console, while I get this error.

Anamnian
  • 417
  • 4
  • 20
CCBet
  • 416
  • 1
  • 6
  • 19
  • Is this the only code you're running? Which version of React are you using? – Andrei Nemes Jul 10 '18 at 10:54
  • yes, this is the only code I'm running and I am running the code at `https://jscomplete.com/repl` – CCBet Jul 10 '18 at 10:56
  • I don't think the error is generated by React. Works on [JSFiddle](http://jsfiddle.net/gtenmbp8/) – Andrei Nemes Jul 10 '18 at 11:01
  • yes, it works on JSFiddle. The course code snippet is executed in JSFiddle. But still, why the error when running in JSComplete? I tried @Tholle's code in JSComplete and I get the same error. – CCBet Jul 10 '18 at 11:06
  • Maybe it has to do with the way JSComplete compiles and runs the code. Have you tried it locally? – Andrei Nemes Jul 10 '18 at 11:11
  • 1
    @Skyp89 It's most likely due to jscomplete trying to `JSON.stringify` what it logs to the console. It will work in other environments that don't do that. `event.persist()` is still needed when the event will be used asynchronously, and `console.log` might be asynchronous. – Tholle Jul 10 '18 at 11:13

1 Answers1

2

Your error is most likely due to jscomplete trying to JSON.stringify what it logs to the console. A React SyntheticEvent has a circular structure, which will give rise to your error when using JSON.stringify on it.

It might work in other environments, but console.log might also be asynchronous. This problem is brought up in the documentation about SynthenticEvent:

If you want to access the event properties in an asynchronous way, you should call event.persist() on the event, which will remove the synthetic event from the pool and allow references to the event to be retained by user code.

So if you plan on using the event asynchronously, the following will work:

function Events (props){
  const clickHandler = (event) => {
    event.persist();
    console.log(event);
  };

  return (<button onClick={clickHandler}> Make an event </button>);
}
Tholle
  • 108,070
  • 19
  • 198
  • 189
  • 1
    I don't see how this would be a problem in OP's code he's not referencing the event object in any async code. – Andrei Nemes Jul 10 '18 at 11:09
  • 1
    @AndreiNemes `console.log` can be asynchronous depending on the [implementation in the particular environment used](https://stackoverflow.com/questions/23392111/console-log-async-or-sync). – Tholle Jul 10 '18 at 11:11