Hacker News new | ask | show | jobs
by xyzzy_plugh 1891 days ago
Is React language or a library? Does it have its own virtual machine? If I'm debugging something that compiles down to assembly, sure, I can use GDB. Why shouldn't I be able to use the JavaScript debugger? Why does React go though so much effort to obfuscate its internals to such an extreme?

There are a million other JavaScript libraries that do not have this problem, for what it's worth.

> It means you don't need to understand the details of how React is implemented.

Isn't this the topic of discussion? Why shouldn't it be as simple as "React stores state in this variable" and I can just poke at it like any other variable?

Abstractions are great, but they all leak eventually. Being able to see through the abstraction is immensely valuable, regardless of where you are in the stack.

Don't confuse simplicity for its pernicious cousin convenience, which usually does not actually reduce complexity, but heralds it.

2 comments

> Is React language or a library? Does it have its own virtual machine?

It's a library, but it does provide a runtime. As such it IMO makes sense that it would have it's own debugging tools. This is pretty common for complex frameworks. Other frontend frameworks like Angular and Vue do it. As do backend frameworks like Rails and Laravel. Or as another example you could look at Unity (the game framework).

You can still use the JavaScript debugger, and I do all the time with React code. But for React specific concepts the React specific tools provide a better experience.

> Why does React go though so much effort to obfuscate its internals to such an extreme? There are a million other JavaScript libraries that do not have this problem, for what it's worth.

It doesn't do it intentionally. It's internals are somewhat complex for performance reasons. Which other JavaScript libraries allow you to inspect their current state with the JavaScript debugger? That's what the React dev tools give you: state inspection. IME, lot's libraries make inspecting that quite difficult (unless they're using global variables).

> Why shouldn't it be as simple as "React stores state in this variable" and I can just poke at it like any other variable?

The problem is that you can't typically poke variables using the JavaScript debugger. To do so you need to get a reference to the variable. And you can only reasonably do that for globals.

> Abstractions are great, but they all leak eventually. Being able to see through the abstraction is immensely valuable, regardless of where you are in the stack.

I guess I've just never hit into the limitations of the React abstraction (and I've done pretty complex things). Nor have I ever hit a bug in the implementation. To me it's like my database or my filesystem: sure it's great to be able to peak under the hood if I really need to, but 99.9% of the time I'm super glad that I don't. I've had much worse experiences with Angular (1 and 2) where I frequently felt like the abstraction was leaking a lot.

As someone who works on and fixes bugs in databases and filesystems, perhaps we don't look at things the same way.
When you have to debug something in postgres, are you going to communicate with it by using netcat and writing your own TCP messages by hand, or use psql? Both should work, but you wouldn't say postgres is obfuscating things intentionally so that you have to use psql (or some other postgres client). The fact of the matter is that complex tools are much more useful if they also come with tools to pave over (some of) that complexity and provide a more useful interface for developer experience.

You can debug React apps just fine without the React developer extension, but in some situations it will be much harder. And to elaborate, I work on React full-time and just use the javascript console and debug messages for 99% of my debugging.

The Postgres protocol is documented extremely well such that it is actually trivial to write messages by hand, and yes, I have used netcat instead of psql.

I honestly couldn't find anything remotely similar in my search for to unearth React runtime internals. Maybe I'm missing something but literally every answer was "just use the extension."

If you want to debug a performance issue in postgres, then the answer will be similar: "just use EXPLAIN ANALYZE". You could get out a C debugger and step through the source code, and there are cases where that is appropriate (e.g if you're working on Postgres itself, or you're trying to diagnose a bug in postgres), but if all you want to do is debug your query then you should use the postgres-specific debugging tool (EXPLAIN ANALYZE).

Same for React. If you are working on React itself, or you need diagnose an actual bug in the runtime then you'll want to use the JavaScript debugger and step through. If all you need to do is work out why your component isn't updating then you can use the React-specific tool (the extension) to make your life much easier.

If you really wanted to, you could write your own renderer. there’s already several: react-dom, react-native, react-test-renderer. Also, I believe there’s at least one conference talk where a renderer was live coded
Maybe you're just not familiar enough with React? The core of it is actually quite simple, it's just a giant while loop tree traversal that gets triggered either imperatively (by calling one of the React.render* functions) or in response to a state change. The VDOM stuff is mostly orthogonal to this, it just improves performance in the browser, but you could technically skip it without losing anything.

Your argument is basically the same as saying you'd rather view HTML as a giant string rather than in a tree view... the devtools basically present something that's linear (the tree traversal) in a tree view, it's not that bad.

Well, parent can find an error in a React app with a standard JS debugger, you can find an error in databases and filesystems with gdb or some such, but not vice versa.

Can be as simple as that: familiarity.

I don't think that's quite it, at least not entirely. They were complaining about how everything they found on how to diagnose and inspect the problem started with downloading a third party tool.

I read this as a complaint that React doesn't provide information on what's going on that you can see and inspect (whether true or not). The equivalent for Postgres would be if they didn't document their protocol and instead referred you to a special debugger they provided, and you had to rely on that instead, making use of gdb or the equivalent much more complicated.

Except the React devtools extension is a first-party tool maintained by the React team [0]. They don't distribute with the library, but given that it's a browser extension there's not really any way that they could.

Also, the react dev tools aren't really a debugger. There's no way to step through code or similar. It just provides an insight into React's internal state (the component tree, and any state contained within it). The equivalent would be Postgres providing a tool to inspect the contents of its caches or indexes, and the OP complaining that they can't read them when using GDB.

[0]: https://reactjs.org/blog/2019/08/15/new-react-devtools.html

> React devtools extension is a first-party tool maintained by the React team

Which makes my example more accurate barring two words...

> Also, the react dev tools aren't really a debugger.

All it takes to be a debugger is to provide additional info about a running process. Insight into React's internal state definitely qualifies IMO. Even if you think it doesn't quite qualify, Chrome Devtools are a debugger, and whether something that extends it to give better info is a debugger or an extension for a dubber is missing the forest for the trees.

That said, I'm not necessarily agreeing with the original premise, since I don't know how hard React is to introspect at this point (I know in the past some websites purposefully made it very hard on purpose). I'm just not sure the original comment's point of view can be boiled down to whether someone is familiar with the technology or not (and part of the reason I'm not sure might be lack of knowledge).

The difference between a language and a library is arbitrary: it’s all an artifact of programming ecosystems that place a hard division between the “language implementors” and the “programmers”: every library of sufficient complexity is an embedded language with annoying syntax.