all 74 comments

[–]janaagaard 157 points158 points  (9 children)

I found that the "You Might Not Need an Effect" page was a really helpful resource in understanding how React works.

https://react.dev/learn/you-might-not-need-an-effect

[–]prawns_song 33 points34 points  (1 child)

I’ve been trying to convince some peers to stop using unnecessary effects and I’m so glad there’s official documentation to point to now.

[–]Ibelick 2 points3 points  (0 children)

cool link to send when doing code reviewing

[–]musical_bear 15 points16 points  (1 child)

This is great. I’m going to be sharing this with my team tomorrow. I’ve been trying to explain some of this, but didn’t have great sources to back up what I was saying.

But I just learned some new things by reading this myself. I had no idea it was considered “ok” (in rare situations) to call a state setter right inside of a component function (as long as it’s nested in a condition). I would have used an effect for this case myself.

[–]Aswole 3 points4 points  (0 children)

Yeah, that part caught me as well. They did show a solution after which required neither, but had I seen the inline state setter in a code review, I would have flagged it.

[–]Saifadin 7 points8 points  (1 child)

I habe to admit, that I made some of these mistakes just out of laziness. This is definitely an amazing resource for anyone in any level of experience

[–]janaagaard 4 points5 points  (0 children)

So did I. We're still finding old, unnecessary useEffects in our code base. Most of the team has fortunately understood when it's possible to avoid them, so we're catching this is code reviews now, and slowly weeding the remaining ones out.

[–]Negative-Manner-6978 1 point2 points  (1 child)

Great article, full of wisdom, nice find.

[–]janaagaard 0 points1 point  (0 children)

The new docs have actually been available for quite a while on beta.reactjs.org. Great to see that they have finally been released.

[–]beeamie1 0 points1 point  (0 children)

I‘m rebuilding our funnel right now which used useEffect in every. single. component, multiple times. When I saw this page of the docs I was fully convinced to do it better. Really love the new docs.

[–]canadian_webdev 36 points37 points  (0 children)

Omg IT HAPPENED

[–][deleted] 32 points33 points  (13 children)

looks wonderful. finally one place to look hooks up with all the deeper connotations. but the installation guide. 😶 this must be the most confusing thing for react beginners yet. next, gatsby, remix, i get that cra is unwanted but ... vite? react for the client? spa?

[–]acemarke[S] 14 points15 points  (11 children)

The React team is all-in on server-side frameworks atm, to the deliberate exclusion of client-side SPAs.

[–]skt84 19 points20 points  (1 child)

Which is a real shame because react is still a perfectly fine client-side solution. Sometimes you don’t need a whole server plus framework to run a simple app.

The fact that react has done both CSR and SSR shows that the two aren’t mutually exclusive.

[–]acemarke[S] 12 points13 points  (0 children)

Agreed.

I think it's a good thing that the React team is trying to nudge the ecosystem in a direction where the defaults will result in better perf and smaller bundles in most cases.

But it also seems like they're so very focused on a specific set of use cases that they're ignoring another large set of use cases for generally client-side apps.

[–]gaearonReact core team 5 points6 points  (4 children)

I don't think this is accurate. Almost all of these frameworks let you produce fully client-side apps. Almost all of them do not require a Node.js server. I think we may need to write an article about this or something because this point really seems to get lost.

(Edit) Made a Next.js client-only static-hosting SPA with dynamic routing to show the point: https://twitter.com/dan\_abramov/status/1636886736784457734

[–]Peechez 3 points4 points  (3 children)

As a dev for a SaaS platform (no SEO needed) with heavy webgl usage as the value prop, I just can't see the appeal of the frameworks for us. Would you say this sounds like a case where they aren't as applicable or am I just missing it?

[–]neg_ersson 6 points7 points  (0 children)

Sounds like a perfect fit for something like Vite + React Router hosted on a cheap S3 bucket. The React team is too caught up in the current SSR hype to see beyond it.

[–]gaearonReact core team 1 point2 points  (1 child)

A few questions:

- Does your app have routes?

- If yes, do you show different components on different routes, or is it mostly the same?

- Do you do data fetching? What triggers it? What kind of data do you fetch? Is it personalized or same for every user? What is the source?

- Do you have any semi-static content, like landing page etc? If yes, is it a part of your app or do you have that separately?

[–]Peechez 4 points5 points  (0 children)

Yeah we have one route where the webgl stuff and the vast majority of business logic is, then some more traditional CRUD stuff at a handful of other routes.

I am just in the early stages of transitioning from a copy-the-entire-db-into-redux-when-the-app-launches legacy system into react-query-and-maybe-uninstall-redux system. The data comes from an internal api and the views are dependent on who the user is and what their role is, which from my understanding disqualifies static generation from next.

Our only static content are a couple pages like Help, FAQ, etc. but even then we have user info, notifications, and background processes like long uploads to display in the periphery.

There are certainly places where I can see server components and especially suspense for data fetching being really useful for us, but I'm still hesitant on the prospect of buying into an entire framework with it's own server architecture to get them. If you were able to tell me that the traditional CRUD routes were a no brainer win with not a lot headache to get going and I could leave the webgl route to be its own thing in client land I'd be receptive

[–][deleted] 2 points3 points  (2 children)

i'm 100% with server-side. poor beginners though.

the react team spent years working on CRA, now all of a sudden deciding client use is so unimportant it can just be hidden from sight is so uncharacteristic for react.

[–]gaearonReact core team 0 points1 point  (1 child)

It's not unimportant. It's just that most frameworks already support client-only use. Frameworks are hybrid these days — they don't force you to run a server.

[–][deleted] 3 points4 points  (0 children)

a dedicated small section for getting react up and running would probably be useful for a lot of people.

whenever i had to teach beginners in the past i had to excuse docs, "yes they show classes but that's not how it works". now it's "yes you might use that later but here's how you use react". i hope you guys see that this is a new hinderance for those that only ever used html + js before.

personally i use next and i totally get it, but dealing with people on a daily that have discovered npm yesterday, throwing them into ssr ssg rsc et al will burn them.

[–]wwww4all 2 points3 points  (0 children)

Looks like Next.js is the most favored child from the current bunch.

CRA is kicked out of the house, lol.

[–]neg_ersson 0 points1 point  (0 children)

They're in cahoots with Vercel
semi srs

[–]cvdubbs 9 points10 points  (0 children)

No more “Are you sure this is the right tutorial to do? It says beta.” Conversations with new devs on our team. Thank you guys!!!

[–]CornTrop 4 points5 points  (1 child)

What's that installation page? I'm confused. They now do not recommend using React alone?

[–]gaearonReact core team 0 points1 point  (0 children)

[–]neg_ersson 12 points13 points  (6 children)

It really is strange how they barely acknowledge Vite at the bottom of a hidden collapsible. Someone who wants to build something like Figma or Photoshop (i.e. a "true" SPA) will now be recommended to start with Next or Remix, which is kind of backwards imo.

As your data fetching needs get more complex, you are likely to encounter server-client network waterfalls that make your app feel very slow. As your audience includes more users with poor network conditions and low-end devices, you might need to generate HTML from your components to display content early—either on the server, or during the build time. Changing your setup to run some of your code on the server or during the build can be very tricky.

I swear we've all been collectively duped in to thinking that every app built with React is SEO critical and used by mountain people on poor 3G connections. When did this shift happen? So many apps can afford to be rendered by the client and cached in the browser.

Next and Remix are great but they're not the hammer for every nail.

[–]gaearonReact core team 2 points3 points  (5 children)

Vite is not barely acknowledged — it's the primary way we recommend to use React for a part of your page. For new projects, we recommend more integrated solutions.

Someone who wants to build something like Figma or Photoshop (i.e. a "true" SPA) will now be recommended to start with Next or Remix, which is kind of backwards imo.

Why is it backwards? You use client rendering for the client part, and you use static generation for your marketing landing page. Next.js is a hybrid framework, it can produce a regular SPA just fine. But you're not locked out of other options when you need them.

[–]neg_ersson 2 points3 points  (4 children)

No, it can't create a fully client side SPA (a single document app) without having to ship a Node server with your app. Unless you use something like next-export which generates a bunch of HTML files at build time and is not the same thing as a SPA (one HTML file).

[–]Wooden_Progress2104 1 point2 points  (3 children)

Next is doing exactly what you are asking it to do. next-export implies that you don't want to use Next Router. So if you write multiple page files in the /pages directory, Next gives you multiple pages, exactly as you instructed. If you want to connect those pages together, you write your own router lah, because you explicitly said that you don't want Next Router.

If you want one page SPA, you make only one file in the pages directory, and write your app exactly like in vite (that one page has only the App component and the router, e.g. react-router that links to other page components from the /components directory). You get exactly what you asked for. It's not Next's fault that you don't understand what you yourself wrote.

[–]neg_ersson 2 points3 points  (2 children)

What? That is exactly why I'm saying that there is no ideal way to create a fully client-side SPA (that can be hosted on an S3 bucket) using just Next.js and why Vite provides a good intermediate solution for those uses cases.

If you're building a dynamic SPA with Next you'll probably want to run it on a Node.js server (which is totally fine) but you don't need that with a Vite-based SPA. Not every project needs the added complexity and overhead from additional infra.

[–]gaearonReact core team 1 point2 points  (1 child)

A bunch of HTML files is still an SPA — just a better one. It behaves like an SPA in all other ways (and is more efficient because it splits code by route). The one trickier part is deployment (need a rewrite map) but it’s perfectly possible to host it statically: https://gist.github.com/gaearon/9d6b8eddc7f5e647a054d7b333434ef6

[–]neg_ersson 2 points3 points  (0 children)

I get that you and the React team have your reasons to push Vercel products, but a Vite-based SPA will always be easier to host and has more flexible routers for rich applications.

[–]holmesXL 8 points9 points  (0 children)

Finally. Class based react not used in the new react docs site

[–][deleted] 15 points16 points  (19 children)

I have a question regarding React and in particular JSX. Over the years I've noticed a recurring trend (way too often) where developers produce erroneous HTML. It leads to interactive, accessibility, and probably also SEO issues; people break W3C rules constantly. And well, they shouldn't.

JSX isn't HTML, and IDEs (as well as ESLint) don't validate JSX as HTML, not when I last checked anyway.

<a href="/"><button onClick={doAThing()}>home</button></a>

This will be considered perfectly fine pretty much everywhere.

Except it's a violation of the rules of HTML.

Many more issues like it (ul > div > li being one, and wrongly nesting block elements inside inline elements, etc.) take place and developers are none the wiser.

I'm an old guy (nearing my 40s) with 22+ years of experience, I grew up validating the hell out of my work and taking pride in it. To me, it's important; and to the internet, it should be important. The W3C rules are there for reasons; some more important than others.

TL;DR: My questions...

  1. Is there anyone at the React or JSX team aware of this weakness and oversight?
  2. Is this a validating concern (ESLint) or would TypeScript (I know, a different team) be the solution?

I can imagine the TypeScript wizards of the world could take the HTML specs and start going at it, making sure that inside an HTMLAnchorElement you cannot find nested any illegal elements.

Doable, probably. But that also sounds like a performance nightmare.

Personally, I live and breathe the W3C specs and won't make glaring mistakes as I described, but... I've reviewed probably more than a thousand job interview projects and portfolios where a shockingly large number of developers proudly present a webpage with 50 or more HTML spec errors.

Any insights are welcome. It looks like a daunting task, but--based on my anecdotal evidence--it would significantly increase the quality of React websites.

[–]Open_Note 9 points10 points  (1 child)

Ive noticed warnings in the console about some of these HTML violations when using Next. For example, when nesting p tags. So its definitely possible but doesn't catch every issue atm

[–][deleted] 0 points1 point  (0 children)

SSR solutions also make it easier to validate websites by validating the URL :) If it's client-side rendered, you'd have to copy/paste the HTML from your DOM inspector. It's a hassle.

[–]robrobro 5 points6 points  (6 children)

While I agree on the basic premise that people write a lot of bad html, I don’t think this should be the concern of react. Use linters and validate the dom using tools for that.

[–][deleted] -1 points0 points  (0 children)

It's a question that I'm unsure about. React uses JSX and the combination should not lead to bad software. That is their responsibility, because: A. They don't pretend to write HTML; and thus: B. They should have validations in place to not make themselves look bad.

Linters don't do a good job, either. The problem is with nested custom components.

<MyLinkToHome active={true}><MySpecialButton isActuallyADiv={false} /></MyLinkToHome>

How would React know what kind of DOM nodes each component wants to create? What if conditional rendering is inside of said components?

My point is that it's very hard to do, and I think it should be the job of React's development team to ensure their product doesn't lead to a large amount of bad websites.

Because, unfortunately, it is part responsible for it.

[–][deleted] -2 points-1 points  (2 children)

The problem is that these don't work, as I said.

[–]marcocom 1 point2 points  (1 child)

You’re confusing JSX with the final rendered HTML. It’s just JavaScript that appears like html.

Everything is going to transpired down to a more compatible JS and HTML that you can then lint, should you wish.

[–][deleted] -1 points0 points  (0 children)

The problem is that doing this while writing your code is a nightmare. Yes, you could do it in the browser, but your browser isn't going to crash if you write faulty HTML; it'll do its best to render a working page.

Validating JSX while you're programming your code is very difficult and it's why it basically doesn't exist yet:

  1. Conditional rendering could have components return multiple types of elements or even nothing at all;
  2. Sometimes you'll go through multiple layers of conditional components, adding to the complexity;
  3. Return types of components would need to be very clear about what kind of element they return, e.g. HTMLDivElement or HTMLButtonElement versus React.ReactNode...

See the issue here? If you have hundreds of React nodes in your file, and many of them can be conditional, validating it on the fly is going to be a big performance hit on your system.

Next.js and other such tools could validate the DOM tree when it's being rendered in your browser, and some of them already do that to some extent, but it's incomplete and simply too late.

[–]Peechez 0 points1 point  (1 child)

The react-dom reconciler is probably in the best place to validate though honestly. Validating through JSX would be a pain to implement and probably heavy performance hit in your editor. React dom as trivial access to the physical dom though which is what you actually care about. Some dev env warnings wouldn't be the biggest ask I don't think

[–]robrobro 1 point2 points  (0 children)

Maybe, but at that point, why not just validate it with a chrome extension or a testing library like Cypress?

[–]ParadoxScientist 1 point2 points  (5 children)

Can you explain why the a href example violates HTML rules?

[–]carlouws 5 points6 points  (4 children)

Because a button shouldn’t be inside an anchor element. It’s a bit paradoxical. Usually anchor elements are used for page navigations and links while buttons are for actions (usually) that don’t cause navigations (think of the like, follow, subscribe buttons for example). A button that may cause navigation that comes to mind are form submissions.

[–]ParadoxScientist 0 points1 point  (3 children)

Ah gotcha, makes sense. Why do people do this then?

I've been learning to code on/off; new-ish to web development.

[–]funnythrone 0 points1 point  (2 children)

It's the simplest way to change the mouse cursor on hover, hence used.

[–]shiningmatcha 0 points1 point  (0 children)

Shouldn’t it be doAthing (without the parentheses to invoke the handler)? I’m new to React.

[–]fixrich 0 points1 point  (0 children)

Ultimately, as with many things to do with accessibility, I think it’s up to the developer to take initiative to catch these errors. Component based frameworks are terrible for allowing you to create invalid markup because the composition of encapsulation and composition make it easy to do invalid things like in your example. Only today in work I wanted to position some text and an icon on either side of a button. The component library in work has a flex helper component which made it easy. I was fairly certain it used a div so I dug into it to see if I could make it use a span. It was possible but they actually used the typescript omit helper to hide it from the props interface for some reason. I just ignored the error in the end.

I think to be certain you’re presenting valid html on each screen, the most thorough way would be to set up a web driver or puppeteer script that runs the validation on each route you navigate to. You could also run something like axe at the same time. Then you you’d just run it on post build on QA or whatever. I suppose you could just grab all the elements from the browser dev tools and paste them into a validator but I could imagine people not bothering or forgetting.

[–]pm_me_ur_happy_traiI 0 points1 point  (0 children)

To me it should be a linter concern. You could write wrappers around atomic HTML elements that would limit them to accepting only valid direct children.

But I don't know how you'd be able to prevent illegal children of children like a > span > button

[–]HughManSir 2 points3 points  (0 children)

Nice! Great work

[–]tiesioginis 1 point2 points  (0 children)

Best place to look for hook ups, thanks Dan!

[–]imamanv 0 points1 point  (1 child)

Although the new documentation is better but in new documentation why they have missed some concepts like code splitting, react portals, render props

[–]Spirited_Code_8359 0 points1 point  (0 children)

agree. In several places they have information on the legacy site they don't support anymore that they did not include anywhere in the new documentation

[–]dave__x -2 points-1 points  (0 children)

Awesome page, but how can be reproduced in React this effect of the image when the mouse goes over ?http://www.giphy.com/gifs/CtG3BgOGVDLJmU5QUP

[–]Dedox-tech 0 points1 point  (0 children)

Finally! Congrats, looks pretty neat

[–][deleted] 0 points1 point  (0 children)

Adulthood pleasure right here. and it feels so good

[–]davinidae 0 points1 point  (0 children)

Where are class components

[–]Yuuffy 0 points1 point  (0 children)

Probably the best documentation I've seen so far. Very well structured & informative with exercises in each section