DEV Community

Dan Abramov
Dan Abramov

Posted on

React Beginner Question Thread ⚛

Hey folks! My name is Dan, and I work on the React team.

I really like the idea of semi-regular “beginner threads” where people can ask simple questions without getting judged. This seems like a great community so I thought: can we try this here? 🙂

We run a thread like this on Reddit but to be honest I'm finding Reddit hard to use and very impersonal so I don't hang out there much.

The rules are simple:

  1. One question per comment.
  2. The questions have to be about React.
  3. No question is too simple! Seriously, ask away, I don’t bite.
  4. Try to keep questions to a few paragraphs at most. If you need a code sample, put it in a gist or, better, a sandbox.
  5. Please reply to the questions too if you know the answer! I might not be able to reply to all of them although I’ll do my best for this thread.

Note this is an experiment. 😉 I don’t know if enough people here are React users, and if the format is a good fit for this website. If that’s not interesting to you folks that is fine too. Cheers!

Top comments (244)

Collapse
 
amypellegrini profile image
Amy Pellegrini • Edited

Is there any particular criteria to prefer class components vs functional components?

I've read many threads arguing about this, in many cases discouraging the use of ES6 classes in general (google "Eric Elliot class"). At least for me is a bit troubling since there are a lot of examples and documentation written using classes.

I have experienced some of the pitfalls of using class in other contexts outside React, although I do not discard these problems being a result of amateur coding skills on my part. Yet similar experiences are shared by more experienced developers.

I would like to hear your thoughts about this, and what is the position of the React team on this topic.

Thanks!

EDIT: Reading below I see that you already answered a very similar question, anyway I leave this one in case there is anything else you would like to add. Apologies!

Collapse
 
dan_abramov profile image
Dan Abramov • Edited

The one thing I encourage you to avoid is inheritance hierarchies. I think classes are okay as a form of organizing code, but work really poorly as a way to reuse the implementation through inheritance. I wrote about this here.

If you just inherit from React.Component or React.PureComponent there’s nothing wrong about using classes. Certainly, they can be unnecessary if your component doesn’t have any state or lifecycle. In this case a functional component would use a tiny bit less memory. However, it is annoying to convert them back and forth when you want to add state and/or lifecycles later 🙂. So that’s really up to you—it doesn’t matter that much either way.

TLDR: don’t create your own React base component classes and hierarchies.

Collapse
 
ssalka profile image
Steven Salka

One notable difference between functional components and class components is that refs (references to underlying DOM elements) can't be used with functional components - has forced me to use a class a few times, even when the component has no state/lifecycle.

A small price to pay for a great library - awesome work Dan!

Collapse
 
royriojas profile image
Roy Riojas

Hey Dan, what do you think about mobx and mobx-state-tree? As state management solutions. Actually I knew about mobx because you tweeted about it, but not sure if you are familiar with mobx-state-tree.

Thanks for all your hard work and patience to answer so many questions in so many places

Collapse
 
dan_abramov profile image
Dan Abramov • Edited

I think it’s great that people find them useful! Personally I’m not a fan of APIs relying on mutability because they make certain fundamental problems harder. For example we’ll need to work with MobX to figure out how to keep them compatible with async rendering in future React versions. It’s probably solvable but mutability makes such problems harder.

I’m also not a fan of wrapping real JS objects and arrays into shims that pretend to be them. I understand why MobX does this but I’ve always considered the ability to work with “raw” objects one or the biggest strengths of React, and I don’t want to give that up.

As for mobx-state-tree, I haven’t looked much at it so I can’t really say. The “fluent” API style is offputting to me but that’s just a knee-jerk reaction so I may have missed important benefits behind it.

Collapse
 
meligy profile image
Meligy

Is there a set of libraries that are recommended for people once they finish the official React tutorial?

I'm not talking Redux, but maybe React-Form, that sort of thing?

Once I know what I'm doing and start doing small PoCs and move from lear-how-this-works to see-how-productive-it-can-be, I'm not sure where to just go with React and maybe native browser promises / fetch / forms etc, or there're de-facto options that can speed me up and everyone is using, and I just miss on them because I don't know what I don't know.

Collapse
 
dan_abramov profile image
Dan Abramov

I don’t know 🙃

When I started with the React ecosystem most of these libraries didn’t exist in the first place so I had to write my own components from scratch. That’s the best way to learn too.

For forms, I’ve heard people rave about github.com/jaredpalmer/formik so maybe I’d try that. For routing, I’d use React Router. As for other purposes, I’d probably start by trying to write my own, and if it takes longer than I want, picking something with the closest API to the one I imagined.

Collapse
 
dan_abramov profile image
Dan Abramov

I don’t use TDD with React so I can’t say. I find it very distracting for UI code because I can’t work on UI without seeing and interacting with it.

I personally didn’t test components at all although I know many people do. If some logic is complex enough I’d extract it from component anyway, and test it separately.

Test whatever breaks in practice 🙂

Collapse
 
radorado profile image
Radoslav Georgiev

Hi, Dan!

Really nice of you posting this thread. Great questions, great answers.

One question from me:

Any plans on creating a router or approving some of the existing routers as the "React Core Team approved router"? Seems like this is painful part of the existing React ecosystem.

Collapse
 
dan_abramov profile image
Dan Abramov

I think we’ve been fairly open about liking React Router 4 🙂 It’s not perfect for every situation but I’d recommend it as a default choice.

Collapse
 
radorado profile image
Radoslav Georgiev

Thanks for the answer :)

Collapse
 
dan_abramov profile image
Dan Abramov • Edited

When we use state and lifecycle methods, the component identity becomes important. On a form with two buttons, two instances of a Button component are independent because each has its own state, and may mount, update, or unmount at different times.

For better or worse, classes are how the vast majority of people think of “identity” in JavaScript (and many other languages). You can design your own bespoke system that creates objects through factories, uses prototypical inheritance directly and whatnot, but you’ll most likely end up with something that feels a lot like using classes. Except that it’s a dialect nobody else is familiar with so you have to educate your users about your pseudo-class system (and maintain it). This is basically why went away from the createClass() helper. We’re in a business of UI libraries, not class abstractions. Sebastian goes into this here: youtu.be/4anAwXYqLG8?t=21m33s.

We might not want to keep using classes forever though. They have their own problems (and I don’t mean stylistic ones). Our two big directions to explore in 2018 are async rendering and compilation. Classes make both of them harder because you can put any field on the this instance and mutate it at any given time. For async rendering, this is a problem because changes can be “stashed” and “reapplied” later (much like Git) but React only knows what to do with props and state rather than arbitrary objects you put on the instance. For compilation, this is a problem because classes are too hard to “fold” statically because you can just do too many things in a class.

So, considering these real issues, we might introduce a different, more functional API for components in the future. However, it is important that it will be informed by actual problems we experience with classes, and not just a stylistic or dogmatic preference.

Collapse
 
ben profile image
Ben Halpern

Oooh acync rendering and compilation both seem exciting.

Collapse
 
devserkan profile image
devserkan

Hello Dan.

I'm a React learner and right now I've digested only the basic stuff. How should we approach to shouldComponentUpdate? Some people, including my friends who have more experience than me, say "consider using it always" since without using it there is so much unnecessary render around and that slows the application. Even one of my friends showed me a real use case of it and his application slows down very much without using it.

The official documentation says "The default behavior is to re-render on every state change, and in the vast majority of cases you should rely on the default behavior."

Should not I use it?
Should I use it when necessary? For example after measuring the performance?
Should I design my application wisely so every render does not slows it down dramatically then shouldComponentUpdate will be unnecessary?

I've read some suggestions but I also want to hear yours.

Thanks.

Collapse
 
sergiodxa profile image
Sergio Daniel Xalambrí • Edited

In my personal experience you should use it only when it's necessary. I found using it almost always a solution to another slow thing. Let me give you a real example:

In a project I worked there was a list of comments (similar to this same list), it rendered 10 comments with all of his sub comments and then using infinite scroll it was loading more comments (and sub comments), but the render was too slow, specially after I loaded more pages of comments (the second time I loaded more comments the page took 10 seconds to update, in that time it was completely blocked).
My first attempt was implement shouldComponentUpdate for each component, and it worked, but after deploying that I investigated more and discovered the code was applying highlight.js to the whole document after each component was rendered and in a sync way, this was causing the super slow render.
So I could have used shouldComponentUpdate and call it a day, but if I did that I was never going to found the real issue.

React is already trying to update the DOM as little as possible, so you don't really need to care about your render method being called many times because it should be fast enough. Also implementing shouldComponentUpdate in any component could cause some unexpected issues like this:

You have a component A rendering a component B, both components are stateful. If A is a PureComponent (or manually implement shouldComponentUpdate) and B change it own state since A is not being updated (its state and props didn't changed) it's going to say that it does not need to update, which cause B not to update (because the React's rendered is going to stop traversing the internal component tree of A).

Another possible issue of using shouldComponentUpdate always is that you're adding more logic which need to be run every time something update, e.g. if your render method take let's say 100ms to render and now you need to run another 100ms logic inside shouldComponentUpdate to check if it should render it means you're still going to wait 100ms always and if the component needs to update it going to take 200ms to do it. Now imagine this everywhere.

tl;dr: only use shouldComponentUpdate if you measure you really need it and not always.

Collapse
 
dan_abramov profile image
Dan Abramov

^^ I agree with this. I’d also note you probably want to use PureComponent when you optimize instead of manually writing shouldComponentUpdate. Then verify with React DevTools (“highlight updates” checkbox) and Performance tab in Chrome (“User Timing” section) that the components don’t re-render anymore. Because the worst thing you can do is to add a shouldComponentUpdate but not verify that it actually bails out when expected.

Thread Thread
 
devserkan profile image
devserkan

Thank you for your answer Dan. I am definitely going to consider using PureComponent instead of shouldComponentUpdate, if I need it of course.

Collapse
 
yhabib profile image
Yusef Habib

I'm provably misunderstanding something when you said:

You have a component A rendering a component B, both components are stateful. If A is a PureComponent (or manually implement shouldComponentUpdate) and B change it own state since A is not being updated (its state and props didn't changed) it's going to say that it does not need to update, which cause B not to update (because the React's rendered is going to stop traversing the internal component tree of A).

Why should B not update? Is this what you meant? codesandbox.io/s/ol4zllpj19

Collapse
 
devserkan profile image
devserkan

Thank you for this good, detailed answer. So, I won't consider using it unless I'm certain of it makes the application better. Using like a very sharp knife, use it only when necessary :)

Collapse
 
mike_gichia profile image
Michael Gichia

Dan, please clarify on the use cases of PureComponent other than stateless components. My understanding of PureComponent is that if misused, will slow down the application rather than making it faster. Since PureComponent will diff the changes before rerender.

Collapse
 
dan_abramov profile image
Dan Abramov

Use PureComponent when you have performance issues and have determined that a specific component was re-rendering too often, but its props and/or state are shallowly equal.

reactjs.org/docs/optimizing-perfor...

Thread Thread
 
michaelgichia profile image
Michael Gichia

Thank you for the clarification Dan.

Collapse
 
amypellegrini profile image
Amy Pellegrini

Here goes another one: what would you recommend as initial steps to participate in React as open-source collaborator?

Thanks again!

Collapse
 
dan_abramov profile image
Dan Abramov • Edited

First, just use React 🙂 You will notice bugs, pain points, etc.

Then, I encourage you to try helping people in the Issues section. A lot of those are just support requests or misunderstandings, but some are legitimate bugs. Even helping verify those bugs and creating minimal reproducing examples is a hugely valuable contribution. Answering React questions on StackOverflow is also a great contribution and grows your experience with the library.

Finally, keep track of the "good first issue" label in the repository. We use them to tag issues that we think are good entry points into helping with React.

I hope it helps!

Collapse
 
amypellegrini profile image
Amy Pellegrini

Awesome! Thanks, will do.

Collapse
 
ben profile image
Ben Halpern

Welcome Dan, definitely a lot of React folks happy to have you around.

We run a thread like this on Reddit but to be honest I'm finding Reddit hard to use and very impersonal so I don't hang out there much.

This definitely jives with the reason we're here in the first place.

Note this is an experiment.

This is great. We'll be following this post for cues on how to build on this sort of post and any feedback from you or anyone is really appreciated.

Now for a question: What are your thoughts on Preact, how does the React team/community interact with spinoff projects like this?

Collapse
 
dan_abramov profile image
Dan Abramov • Edited

What are your thoughts on Preact, how does the React team/community interact with spinoff projects like this?

I think it’s cool that people want to stay within the React paradigm even if their tradeoffs don’t match ours.

At Facebook, we typically use React for applications that are truly dynamic and need to scale well with the application size. We don’t use it for stuff like landing pages or extremely thin apps. So in our case the difference between 3 and 30 kB gzipped is less pronounced because the vast majority of the code comes from the application itself.

For our use cases, supporting older browsers consistently and having great runtime performance is more important. We're also still working on React, and as we enrich its capabilities we're hoping to bring down the repetitive code in the product (e.g. for data fetching). We think will be more impactful because, unlike the library, the product code keeps growing over time.

We don't really interact with these projects as much, but we hope they continue to be useful to the folks who rely on them, and will happily welcome these users back if they decide React better answers their tradeoffs later. 🙂

Collapse
 
samithaf profile image
Samitha Fernando

Could be a silly question since I have not used React much. Recently i saw a code base using react and could not find much of unit testing. But there are lot of "snapshot" testing with Jest. I think that Jest internally compare a previously generated text output with current and break the test if it is different. But i don't think "snapshot" tests can totally replace unit testing since "snapshot" tests can't really test interactions isn't it?

Also how "snapshot" tests fit in to TDD?

Thanks.

Collapse
 
dan_abramov profile image
Dan Abramov

Snapshot tests aren’t meant to replace unit testing. They’re complementary. I suggest using snapshot tests for cases where otherwise you wouldn’t have written any tests at all.

People have different opinions about how much unit testing is useful for components. When I was building products with React I didn’t write unit tests for components at all because they were changing too often, and adjusting tests all the time would slow me down. And if some logic is complex enough to be worth testing I would extract it out of the component anyway. I also definitely didn’t use TDD for components (my personal opinion is that TDD isn’t very useful for UI code in general).

But this is tradeoff is different for every team. Some teams find more value in unit testing components. You definitely can do this with React—either with react-test-renderer or enzyme. It is up to you to decide how to balance unit tests with integration and snapshot tests in your app.

Collapse
 
samithaf profile image
Samitha Fernando

Thanks for the rapid response in the Christmas day! Another question regarding HOC. How HOC is different from decorator design pattern?

Thread Thread
 
dan_abramov profile image
Dan Abramov

I guess it’s a React-specific variation on it?

Thread Thread
 
samithaf profile image
Samitha Fernando

Probably :) but I can't really confirm since I have not used HOC in depth.

Collapse
 
duncanhaywood profile image
Duncan Haywood

Hi Dan,
Thank you for sharing your insights here. You are helping me very much in my own practices of implementing tests.
Much thanks,
Duncan Haywood.

Collapse
 
daniel15 profile image
Daniel Lo Nigro

But i don't think "snapshot" tests can totally replace unit testing since "snapshot" tests can't really test interactions isn't it?

A snapshot is simply a different way of performing an assertion, instead of using expect(...).toBe(...). You can write any type of test using snapshots.

Collapse
 
dan_abramov profile image
Dan Abramov

That’s a great point, you actually can test interactions with multiple snapshots.