How does `console.log({target: event.target})` work in React?

I’m learning how you can use event.target to get the value of an input form in React.
If I write console.log(event.target), I can see the JSX form in the console.

However, if I write console.log({target: event.target}), I can inspect all the properties of the DOM object I’m looking at. Am I assigning event.target to a property on an object with no name? How does this work?

I’m studying this tutorial: https://egghead.io/lessons/egghead-make-basic-forms-with-react

The part I’m discussing starts at 1:02.

Without looking too much into it, I can tell you that there are ways to change how objects are displayed in the console. Since event.target is a React component, it’s likely that Facebook engineers have customized its console output to display the JSX version as a string because this makes debugging much easier. When you pass an object literal, the console representation would be different, probably calling JSON.stringify on itself, including all of its children. This would give you a more conventional output for event.target only when it’s in another object. Try console.log(JSON.stringify(event.target)) and see if you get the same output.

Hey thanks for the explanation. I’ve been talking to some other people and doing some google-fu and what I’ve found mostly matches up with what you said.

I think this part you mentioned

Since event.target is a React component, it’s likely that Facebook engineers have customized its console output to display the JSX version as a string because this makes debugging much easier.

It’s actually just a quirk of console.log rather than something engineered by the React team.

This is from the console.log doc:

Please be warned that if you log objects in the latest versions of Chrome and Firefox what you get logged on the console is a reference to the object…

I think you’re on the right track about JSON.stringy but for reasons I don’t understand that doesn’t work. It gives me this error: TypeError: Converting circular structure to JSON.

However console.dir(event.target) gives me the same JSON-like output as console.log({target: event.target}), which is what I would also expect from your suggestion.

This isn’t related to string representations. The logging of object references is something that trips up a lot of people when debugging (myself included). Copy and paste the following all at once into your console:

var a = [1,2,3,4];
console.log(a);
a.push(9)
console.log(a);

At first, it will look correct, but when you click the disclosure arrows to inspect the contents, both logs will be the same. This is because you’re inspecting a reference to the object, not an instantaneous printout. This is what the next sentence in the docs describe:

which is not necessarily the ‘value’ of the object at the moment in time you call console.log(), but it is the value of the object at the moment you click it open.

What I’m talking about is overriding the object’s toString method to change the way it’s represented as a string. Try this:

var x = new Object();
console.log('' + x);  // This coerces x to a string; should be "[object Object]"
x.toString = () => "This is x";
console.log('' + x); // should now show "This is x"

You can change how objects show up in debugging this way, and it would be straightforward to do this when React is compiling. It could take the JSX as a string literal, create a function to output that string as the toString method of the component, and let the error handler coerce the object to a string. Again, I don’t know that this is what happens, but it’s not a particularly wacky idea.

1 Like

Hey sorry for the late reply, but your examples were helpful in me understanding console.log. Cheers!