But only because React, with transpiling and the shadow DOM and all that is so inscrutable.
There’s no hope of understanding the DOM with React, no hope of understanding styles with styled-components.
There’s no hope of placing a breakpoint in your code and tracing forward through events. No hope of understanding stack traces.
The DevTools begin to address some of those deficiencies. It does help, but still leaves me thinking the tradeoffs weren’t worth it. You can never reach simplicity, only manageable complexity. In the long run it leaves an opportunity for a new generation of tools that respect JavaScript and the DOM.
There’s no hope of understanding the DOM with React...
You can still understand the DOM in a React driven app though. The component output is there for anyone to read. I do that every day. All React is doing is generating DOM content and then working out the smallest update necessary when the state changes. The problem that React Devtools addresses is that it's the component output that's there, not the components themselves. There's more information behind the scenes, and that is what React Devtools lets you peek in to.
It does help, but still leaves me thinking the tradeoffs weren’t worth it.
You have to reason about the way you write code, what your apps need, and what works best for your users. If the tradeoff is that using React's features means you can no longer work with the complexity of what's happening in the browser and that's slowing down your development process then don't use React. Your development process and your users are way more important than any framework.
> You have to reason about the way you write code, what your apps need, and what works best for your users.
Not to use too-harsh language but that's a cop-out in my opinion. Yes, some tools are better for a given job than others. But we're working with general-purpose machinery for the purpose of building UIs and applications. There isn't really a differing set of requirements or problems in that domain. ... and if that's true, then it means that one size should actually fit all. I think, personally, UIKit is excellent. I think people don't understand how to use it properly… they don't understand how to write good imperative code, so they look to a declarative system as a way around that… but I think they're only deferring the inevitable or shifting non-problem-inherent complexity they couldn't initially solve.
What’s wrong with the in-browser DOM inspector? I’ve never run into a problem with React, it’s output, it’s error messages, or anything else such that I couldn’t trivially dive in and fix. I’ve never once felt the need for React DevTools in my 5 or so years of React.
I remember AngularJS well, that’s a framework I can do without.
There's a problem when you set breakpoints trough DevTools and instead of Chrome breaking on that line, you end up in some VM1234 file with a bunch of minimized react core code in it.
for me, a lot of it is simply not having to go in and add in console.logs to everything to see what props and state are, you can just explore around instead
Time-travel debugging is miles better than the old way of placing breakpoints. For me, debugging with breakpoints was always a pain. I often skipped through stuff accidentally and had to start all over again from the beginning, or accidentally went inside some third-party library code that I did not intend to, or placed the breakpoint at the wrong spot. It was just slow and inconvenient, unlike React DevTools where you can see every change and step forward or backward, replay events and observe the state at various points without having to put watchers on every variable / expression.
You can return back to the previous statements in any decent debugger instead of starting from scratch. And by default they don’t go inside third party libraries unless you specify that it’s what you want. What kind of debuggers were you using?
Visual studio, rider, IntelliJ idea, eclipse, they can all do it, although the last two can only go to the last stack call instead of moving to the specific statement if I recall correctly.
You can move around the execution in the VS debugger - if you’re at a break point you can move execution earlier in that function etc. That’s the only debugger I’ve seen doing that though.
You can also use the “restart stack frame” option in Chrome DevTools to move back to the beginning of any function currently being executed. So if you skip past something on accident, you can just restart the closest stack frame to bring you back.
> It does help, but still leaves me thinking the tradeoffs weren’t worth it. You can never reach simplicity, only manageable complexity.
100% agreed. May I shamelessly plug my enormously positive experience with Elm here, with DOM being DOM, always-present time-travelling debugger, no runtime exceptions and other nicities? Main point is that you don't have to do the tradeoffs sometimes if you go full way towards a different, pure, statically-typed language.
The analog of styled-components exists, but I never used it, just regular BEM+SCSS.
"There’s no hope of understanding the DOM with React"
This is false. I've been developing with React for over a year and a half and have never used the React dev tools. I've only ever used the browser's web inspector and it's fine. We don't write CSS in JS, so this could play in to that, but when we were evaluating those solutions it wasn't impossible to figure out what was going on, even if you had hashes for class names.
One of the reasons why I love webcomponents. It’s a simple api and plays well with the dom. Wanna innerHTML some string? Boom it works. document.createElement(‘my-foo’). Works. addEventListener. Works.
Dom explorer shows the elements. document.querySelector finds your tags. Css just works. Nothing new to learn.
Custom elements let you be just another html tag and do your magic. Not fully sold on shadow dom but web components api is simple and I love it.
All of these things work with React, too. React appropriately names the prop to "dangerouslySetInnerHtml" because it's vulnerable to XSS attacts and a lot of beginner web developers don't realize that.
CSS has of course always worked just fine with React (as does LESS and SASS). Styled-components is totally optional.
There's tradeoffs at scale with trying to use an imperative style of coding with document.querySelector or JQuery. Fine for simple websites. Absolutely awful for complex web apps with large teams.
Dom explorer is still a tab in Chrome for react devs. I readily switch between the React devtools and Dom explorer all the time.
The reason in my mind, for React, is that it's a higher level, functional abstraction above the DOM that makes complex web development manageable.
One of the downsides, depending on implementation mostly of course, that you still need JS to render your component. I prefer server-side rendered HTML over both React and web components because of the compatibility.
After showing the HTML you can still make elements more interactive with things like jQuery, Stimulus or Freudjs (disclaimer: my own)
It's great to a point, but when front grows complex enough you sooner or later realize you're repeating a lot of backend logic on the front, and doing a lot of manual labour keeping track of all states, events, etc. What div is visible, which one to hide, which buttons to disable, adding new rows into forms dynamically with pre-populated values... that kind of stuff is way (and I mean waaaay) easier when coded in a declarative reactive way.
> later realize you're repeating a lot of backend logic on the front
So you mean something like keeping state of forms in something like redux and sending out an event every time you press a button so that state gets update and the change is pushed down the tree of elements so that the letter you just pressed gets rendered in the form?
Or did you mean client side validations of forms that you also have in your back-end?
Obviously you didn't and I am being a bit of an ass, but this is what is the somewhat recommended way of going around this and it is so convoluted.
> doing a lot of manual labour keeping track of all states, events, etc.
The state of most web applications can be kept inside of DOM elements and the url just fine.
> What div is visible, which one to hide, which buttons to disable
This is where CSS-classes and the aforementioned JS libraries come in and they do this job just fine.
> adding new rows into forms dynamically with pre-populated values... that kind of stuff is way (and I mean waaaay) easier when coded in a declarative reactive way.
I don't believe you are right. It is not easier at all to add some DOM elements with React than it is when you use small bits of JS. Let's say you use jQuery, then it is 1 dependency you add with a small wrapper script for your dynamic form, with React you add thousands of dependencies and you have to build your complete application in React just to dynamically add a row in one of the forms. How is that easier?
I don't think I'd build Slack mostly using HTML rendering from the back-end, but most of the things that we build are CRUD applications that can easily be built using things like Ruby on Rails. Let's say the Trello's, Githubs and Amazons of our world.
> with React you add thousands of dependencies and you have to build your complete application in React just to dynamically add a row in one of the forms. How is that easier?
Because with sufficiently complicated UI you will simply at some point have to start writing abstractions and libraries to help you handle all that mess, and then you'll basically end up building a good part of those "thousands of dependencies" yourself - reinventing the wheel.
For smaller projects it's an overkill obviously, no one says you have to use it everywhere. But for bigger projects it's a way more optimal to sacrifice some performance in order to be able to build faster and maintain the project easier, and even if you try to make your own solution chances are that with time it will evolve into something very close to how big players solve it. At least that's what happened to all my custom frameworks (front and backend), 10+ years ago when I myself still believed in not needing extra bloat of frameworks... you one day realize that someone already solved your problem, and solved it way better than you ever would...
> Because with sufficiently complicated UI you will simply at some point have to start writing abstractions and libraries to help you handle all that mess, and then you'll basically end up building a good part of those "thousands of dependencies" yourself - reinventing the wheel.
And oh lord have I seen the result of these home brew “not a framework but actually is a framework” frameworks. They are all a rats nest nightmare for anybody but the original developer to work on.
The first thing that happens when the original developer moves on is the whole thing gets rewritten using the framework du joir.
This is an argument that I often see from people trying to defend front-end frameworks. That mythical complex UI. So far the only thing I can imagine that comes close might be something like a chat application. Apart from off-line ready apps, I grant you. In that case there would be no point in trying to accomplish that with vanilla JS or jQuery.
> But for bigger projects it's a way more optimal to sacrifice some performance in order to be able to build faster and maintain the project easier,
I am arguing that you build slower if you build your front-end separately from your back-end rather than use something like Ruby on Rails.
> you one day realize that someone already solved your problem, and solved it way better than you ever would...
I am saying the problem isn't there 95% of the time. You are just better off rendering HTML and some small pieces of JavaScript.
> 10+ years ago when I myself still believed in not needing extra bloat of frameworks...
I don't believe this at all, I just oppose the current state of affairs in the JavaScript world and don't subscribe to what is generally considered a good stack. I am not saying you should reinvent the wheel either, I am talking about existing tools like jQuery or Stimulus JS.
> So far the only thing I can imagine that comes close might be something like a chat application.
Sorry, but if you think that chat is a complex UI you obviously don't understand what type of complexity I'm talking about. Multi-page, multi-level forms with a lot of conditional rendering are far bigger problem to handle than chat. Challenge is not in a single particularly advanced action, forms I'm talking about are mostly just a bunch of ifs and event handlers that update the DOM accordingly. Problem is the overall complexity arising from a sheer number of different combinations you need to control, so you end up with thousands and thousand of lines of jQuery functions and events interacting and stepping on each other's toes.
For instance I'm currently working on an IP management app for big, international law firm. In order to invoice a client for even a very basic service like trademark registration you need to handle multiple countries, multiple laws, multiple currencies, and it has to be all in one dynamic form because they need to fill hundreds of those and it has to be simple and quick. These forms are huge, each loads a dozen of subforms, dialogs, etc. conditionally based on different business and legal rules that apply and user has to be able to edit all of that interactively. I've built the first version of that app 10 years ago using jQuery and it worked for a long time, but it took us more than 3 years to fully finish and it was huge and hard to maintain and had a number of limitations, as some legal rules were just too complex to handle. We now did a new version in Vue in less than 6 months. Much easier, much cleaner, our code deals just with our logic, not touching DOM at all, so it's much easier to debug and maintain it. Overall much nicer experience and thanks to that we were able to solve a number of problems that the old version had.
And this experience translates to pretty much any serious business web app that I've ever built.
I mean who'd do that when there are plenty of server-side templating solutions that don't have to live by React's constraints (vdom/DOM diffing) only making things difficult? The only use case for React SSR seems quick first-page rendering and SEO.
what happens when you want some interactivity after the initial load? That's why you SSR React. If you used a serverside template then once the page loads, how do you deal with interactivity? jQuery? Plain JavaScript?
Yes why not? If you already decided your site is content-oriented by choosing server-side templating, then interactivity will be limited in scope and easily implemented using either vanilla js or jquery, or even basic HTML forms, links, and CSS menu tricks without js at all. In my experience, while I personally like React when it fits, I've seen too many projects that don't benefit from a MVw approach where React or Vue or another MVw framework seems like a decision by developers to pad their resume, or even by managers to win developers by giving them, like babies, something to play with and show off to their peer group when in reality the app is just a basic LOB application, like the old legacy app it replaces.
It is, but I meant more in a 'traditional' way, so rendering with some templating engine whose abstractions aren't so far detached from HTML as they are with React. Mostly by mixing some dynamic parts into HTML rather than the other way around.
A React application gets applied to a certain DOM element. Inside of that application are multiple layers of containing elements that handle things like routing or processing different events on existing DOM elements or triggered remote calls.
If you add redux and something like redux-form you end up with sending each keyup event to the redux store and re-rendering your input fields from that store.
So yes the JSX at the very bottom of your software tree is pretty much like HTML, but it takes a whole lot of engineering to get there and variables get pushed through many layers before they reach the final JSX in which they are rendered.
Some of this has to do with how you implement your application, but in general getting from input to output takes more steps than it does with a server side rendering framework.
This is fine when building something like a mobile application or an off-line-ready application like devdocs.io, but if you use a React application in front of some back-end you are just getting HTML in return for all your engineering efforts. If HTML with a few interactions is all you are after there is too much code and too many layers between the page that has your `<div id='myapp' />` and what you get after React is done rendering.
Sure, I get that. What I'm saying is -- if you prefer to keep things simple and use server rendering, using server rendering alone with React (no routing, Redux, etc) is pretty much identical to using templates.
You can treat React itself as a single-pass server template engine with component support. You don't have to bring all of this single-page app stuff into it. Hope that explains my point. You don't even have to run React on the client at all.
I'm specifically talking about ReactDOMServer.renderToString() on the server and serving that HTML. Not "mounting into a <div>" client use case.
Yes you are totally right. JSX in itself and the way you can nest React components, etc is very nice and could be great as a template engine. I should have said more clearly that I meant React et al. in the context of rendering everything on the client-side.
> There’s no hope of understanding the DOM with React, no hope of understanding styles with styled-components. There’s no hope of placing a breakpoint in your code and tracing forward through events. No hope of understanding stack traces.
Agree. IMHO the fact that React uses the virtual DOM is one of its biggest inconveniences.
> In the long run it leaves an opportunity for a new generation of tools that respect JavaScript and the DOM.
Angular (v. >= 2.x.x) on this is much simpler to understand as it manipulates the DOM directly. With the built-in dev tools of any browser you pretty much can inspect any portion of HTML, CSS and source code.
One thing I like about having React DevTools installed is you can easily see which sites use React because the little icon lights up. It's a surprising amount these days; React is getting so popular.
From my PoV, React is already past its maximum in the hype cycle, and I see customers choosing vue.js most of the time. I have no stake in this (haven't worked with vue.js, nor with new React with hooks etc.), but presumably vue.js is chosen for React-like MVw without the jsx/babel+webpack build step drama, as a simple js lib.
Ironically, my understanding is that it’s Vue that requires a compiler for even basic component support. If you don’t use webpack or similar tools with Vue, as far as I know, you can’t declare an idiomatic reusable Vue component.
With React, whether you use Babel/JSX/Webpack or not, components are always available. They’re the whole point.
I think it’s fair to say that Vue is initially more familiar to and easier to get started with for folks who are more comfortable with HTML. React is more JS-centric. Even though in the end they render the same DOM elements.
Hm, then it's indeed a misunderstanding on my side. I definitely need to take a look into vue, but I thought people were choosing it over React because they didn't like JSX but would prefer straight HTML (though again, I don't know vue and how it would be possible for vue to render components based on just HTML syntax).
Vue offers a more gradual learning curve coming from HTML. Because in the beginning, you don't write components in JS at all. Instead, you can use Vue "directives" like `v-if` right inside your HTML. Later, when you're ready for components, you have to add a compiler.
React takes a different approach. It doesn't "pretend" to be HTML by extending it with custom directives. Instead, it forces you to start the journey in JS land. That can be frustrating at first if you're unfamiliar with JS. But the gap between "simple" and "complex" is smaller: you learn the idea of components once, and can apply it with or without a toolchain.
That is the exact reason I prefer React - Vue feels like you are mixing HTML and code when you start adding in the directives. JSX feels quite natural to me, in particular because it provides an easy mechanism to code with a clean break between the app logic vs. rendering.
I know at the end of the day, they both still come out as HTML and JS in the browser, but React just feels cleaner. At least to me.
most tutorials do "excalate quickly" and introduce the vue cli within the first few minutes, which is probably what most professional teams use to manage today's frontend build step (drama).
As if the improvements of the dev tools weren't enough, they've created a sweet interactive tutorial (https://react-devtools-tutorial.now.sh)! Don't know it it's new, but I'am very impressed.
I was impressed to see how well hooks worked when attaching Vscode to a chrome instance in debug mode. They just show up in the list of closures at your breakpoint. Maybe I need to try harder but I haven't been needing react dev tools.
Does anybody bother to go through this codebase? It's a great tool, but Facebook is the last company I'd want to have the obscene privileges that extensions have.
Brian goes into more detail on why we originally added these permissions during the rewrite, and why we were able to remove them: https://www.reddit.com/r/reactjs/comments/cqx554/introducing.... (TLDR: some were for features we ended up cutting; others had easier workarounds that didn't need these permissions.)
> but Facebook is the last company I'd want to have the obscene privileges that extensions have.
reply
Sounds like you're talking about extensions in general, but for what it's worth- React DevTools doesn't require any super deep permissions¹ and all of the source code is in the open².
Yeah, but the intent is to drive developers away from the building blocks of web and weaken the value of HTML standards and accessibility guidelines that make the web awesome. Evil has many masks. And a corporation powered ‘open source’ is now the worst evil monster we have had to face in decades.
To give some context. Historically React has been all about sharing what worked for us at FB for creating dynamic, complex apps. If it doesn't work well for you, please don't use it. There are plenty of alternatives.
The notion that there's some kind of plan to "weaken the web" there just isn't true. I don't know what you're basing it on. You may not remember this, but when React came out, everybody laughed at it. It was not some kind of asset for Facebook at the time. If we talk about motivation, ours is quite the opposite. We want to empower web developers to create complex UIs, comparable to native apps. We very much want the web to win, or at least to stay relevant.
The only reason React got open sourced and kept being developed in the open was because engineers working on it wanted to share it with the wider web community. They saw something useful in it. Eventually, the industry took note, but it wasn't until a few years later. We believe in open web, and this is why we work on React.
The notion that React is at odds with accessibility is also mistaken. React outputs regular DOM, and common React setups like Create React App include more accessibility checks than you'd get writing HTML by hand. Maybe you're confusing React with something else?
Yes, keeping dynamic JS apps accessible has its own set of challenges (we document some here: https://reactjs.org/docs/accessibility.html), but it's not React that makes it hard. It's the dynamic UI expected by users that makes it hard. If anything, in my experience React makes it easier for teams to adopt better accessibility practices by putting them directly into React components (example: https://ui.reach.tech).
Finally, concerning standards. We've worked and will continue working with standards committees to bring good parts of React into the platform. For example, the "object spread" operator in JavaScript was originally added to JSX, and was championed in TC39 by a React team member. Similarly, we're closely working with standard bodies to improve web app responsiveness. Not just for React, but for all libraries. You can learn more about this work here:
> We want to empower web developers to create complex UIs
> We very much want the web to win, or at least to stay relevant.
> We believe in open web, and this is why we work on React.
Who is “we” in these sentences, Facebook or the React team? If it’s the React team, then what is Facebook’s motivation? If it’s Facebook, then why on earth would anyone trust it?
The discussion here is motivated by distrust for Facebook, and suspicion about their (your) motives. The specific accusations in the thread above are perhaps a bit out there, but I don’t think it’s addressed well by focusing on the history of React but ignoring the history of Facebook.
React has become, for better or worse, one of the building blocks of the web. Synchronous updates were always a pain, properly encapsulating components was always messy and fragmented, and now there's a standardised way to do asynchronous DOM updates using encapsulated components.
Hooks still show up without variable names associated with them (I say still because I was using this before release). I assumed they would try to find a way around it. In the current state the hooks support is useless.
It's a little scary to upload a completely new version, when you know there's that many weekly active users that are going to be hammering away on it soon.
Is this the same program that, if a project has installed, tries to make a bunch of websocket requests from the app to the browser plugin, which if non-existent causes your console and network tab to be flooded with failed websocket requests?
I'm surprised that everyone's looking confused here. Yes: since 2016 (React Native v0.32), at least on iOS, React Native apps in development mode try to open WebSocket connections to standalone React DevTools at startup and indeed flood your console with cryptic messages.
Thanks, Dan! The incessant console-flooding was actually one of the things that made me give up on React Native. Great to hear that this is being addressed.
> But unfortunate it's not enough. Especially because other websocket created in RCTPackagerConnection (funcition socketForLocation) and as I can see it can't be disabled from AppDelegate :-(
Maybe the Chrome/Firefox DevTools don't, but the standalone React DevTools most definitely depend on WebSockets. My custom React renderer can't connect to them without shimming in a WebSockets implementation, for example.
But only because React, with transpiling and the shadow DOM and all that is so inscrutable.
There’s no hope of understanding the DOM with React, no hope of understanding styles with styled-components. There’s no hope of placing a breakpoint in your code and tracing forward through events. No hope of understanding stack traces.
The DevTools begin to address some of those deficiencies. It does help, but still leaves me thinking the tradeoffs weren’t worth it. You can never reach simplicity, only manageable complexity. In the long run it leaves an opportunity for a new generation of tools that respect JavaScript and the DOM.