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 (240)

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
 
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

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
 
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
 
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
 
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
 
isaac_jzr profile image
Isaac

What is the best alternative of binding this in the constructor?

Collapse
 
dan_abramov profile image
Dan Abramov

I tend to use class properties:

class Button extends React.Component {
  handleClick = (e) => {
    // no binding
  }
  render() {
    return <button onClick={this.handleClick}>hi</button>;
  }
}

Note they're not standardized yet. But they're so widely used that if the syntax changes or proposal gets dropped, there's definitely going to be an automated migration path (i.e. a codemod).

Collapse
 
shahor profile image
Shahor

Although it looks quite cool I'm really not at ease with class properties because of how they could be confusing, scope wise.

A fat-arrow function is supposed to be bound to the lexical scope in which it is defined and that is very much not the case here, which could lead to some confusions.

I don't know exactly where to stand :D

Thread Thread
 
dan_abramov profile image
Dan Abramov

We’ve been using them in production at Facebook for about a year now, and haven’t seen much confusion in practice.

Collapse
 
matthras profile image
Matthew Mack

As a React newbie this is a game-changer for me. No more headaches with debugging just because I forgot to bind this to functions in the constructor!

Collapse
 
adamthewizard profile image
Adam

Can't believe how old this comment is now! I still check it all the time for syntax lol - It's literally become it's own google search for me! Thanks for the (probably)10+ times this has helped!

Collapse
 
abhirathore2006 profile image
Abhimanyu rathore

i go for following

  1. bind only if you need it in children Component or Event
  2. Re-using same function ? try to use "Call" if that becomes complex then use bind.
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.

Collapse
 
liana profile image
Liana Felt (she/her)

Hey Dan, thanks for doing this. What would you say is the latest best practice for approaching CSS/styling in React?

Collapse
 
amypellegrini profile image
Amy Pellegrini • Edited

Liana, I don't know if this could be considered a "latest best practice", but it is something I've started doing for my own projects, which is to import CSS files as modules import "./component-style.css" inside the component file, then use Webpack to compile it.

You can avoid errors during testing using ignore-css module.

If you research a bit there are very interesting articles on the topic, and it has helped me to keep my CSS modular and clean.

You can even keep your CSS file close to your component.js and component.test.js files in the same folder, which for me at least is very practical when working on any particular component.

Hope it helps!

Collapse
 
rip21 profile image
Andrii Los

Or you can just use styled-components and all that will be very natural with zero dead CSS code :P

Collapse
 
rip21 profile image
Andrii Los • Edited

I'm not a Dan Abramov :D But still, react is lightweight library so I'm not sure that they will add any "CSS-in-JS thing" to it that is more complex than inline-styles that they have now.

About best practices now and what community is fascinated about is surely CSS-in-JS libraries.
Such as styled-components, jss, glamorous.

They have automated out all styles isolation problems keeping the ability to work with 3rd party CSS styled components.
At the end, we have:

  • perfect props dependent styling
  • isolation
  • styles encapsulation within the component

And many other things like discoverability of usage, modularization of the styles, so you don't have any unnecessary styling applied to the page, dead simple theming support, lot's of reusable functions, mixins, shortcuts and everything you can imagine cause it's just JS.

You can analyze it using way more tooling than CSS have, you can programmatically do tons of stuff etc.

If you want an example of usage of styled-components which is the most popular solution, for now, go ahead here.
codesandbox.io/s/21nx9pw8jr

I highly recommend styled-components.

About more traditional things, well, postcss with CSS modules and cssnext preset is a nice thing for old-fashioned people, but is way-way-way-way weaker than styled-components and jss and glamorous in terms of natural use with React and component way of doing things.

Collapse
 
dan_abramov profile image
Dan Abramov

Hey! I don’t think there any “best practices” because the field is still evolving and there are many unsolved problems. If I were to create a project I’d probably still use plain CSS 😅 Facebook uses something similar to CSS modules (but with a different syntax) and that works okay-ish too. In side projects I’ve enjoyed using glamor but I don’t really have any opinions there.

Collapse
 
mcintyre94 profile image
mcintyre94

What characteristics (if any) do you think describe apps for which React isn't suitable? I'm guessing particularly small/simple apps wouldn't benefit, but does anything else come to mind?

Collapse
 
dan_abramov profile image
Dan Abramov
  • Apps where hundreds of things on the page constantly update at the same time over a very small interval. For example stock trading apps. You don’t need the expressiveness provided by React for most such apps, and optimized templates (e.g. Angular AOT, Glimmer) will be faster for these use cases because they skip the component abstraction.

  • Primarily static websites. However that really depends on how you use React. For example we actually do find it very helpful for the (mostly static) reactjs.org website but we can do this because we use it through Gatsby which generates a static website from React components. This is very different from just adding using client-rendered React components for everything.

  • Embedded widgets. By nature they’re supposed to be as tiny as possible, and there isn’t much of an “application” in them anyway. I guess you could use something like Preact but perhaps plain JS or something like Svelte would still be best for these cases.

Collapse
 
aswathm78 profile image
Aswath KNM

I'm a beginner in JS world . So What are the concepts that I should know to learn and use react easily .

Many of my friends said react is not actually a beginner friendly one . So they asked me to try angular or polymer etc...

Is that so ?

Collapse
 
naren profile image
Naren Arya • Edited

React is a very lean library that one can easily learn. As a developer worked with Angular JS and Angular>2 before, I felt react is less opinionated, fun and, easy to learn. The react's component based development is far more well thought than the AngularJS's two way data binding & controllers. Angular >2 is a very opinionated framework that takes a long time to master.

Beginners who try React for the first time easily gets scared by the diverse tutorials out there. They use things like JSX, ES6, Webpack, Redux which annoys beginners and creates a pseudo humongous learning curve. Instead, you(a beginner) can straight forward include react.js and react-dom.js in your HTML and start creating components(like Angular JS).

Read this book, if you have a chance:
shop.oreilly.com/product/063692004...

It teaches you react from plain JavaScript's view. After reading this, read the official docs and everything makes sense to you.
reactjs.org/docs/hello-world.html

For more tutorials on React, visit this.
github.com/markerikson/react-redux...

Note:
First, learn JavaScript well. If you are good at JS, understanding a library is an easy thing. Reverse may not be true.

Collapse
 
dan_abramov profile image
Dan Abramov

I think it’s very subjective. I know a lot of people who learned JavaScript through learning React. I think the main difference is that React embraces JavaScript instead of trying to hide it from you. So you need to get comfortable with the language. The upside is you don’t just learn a library, but actually learn the language you’re working with 🙂

I don’t think you need to know much to get started. To feel comfortable you’ll want to understand JS syntax and concepts (functions, classes, binding).

Really, the only sure way to know is to start going though our docs (reactjs.org/docs/hello-world.html) and/or the tutorial (reactjs.org/tutorial/tutorial.html). Try it and see!

Collapse
 
ryanrundle1 profile image
Ryan Rundle

Agree with Dan (not that you need me to). React is more like Javascript than Angular (I've used both) and most other frameworks, it really does embrace Javascript. I also feel like React embraces functional programming which is a good way to build good habits.

I dove into React as a beginner and found it much more beginner-friendly than most other frameworks or libraries. Beginner friendly doesn't mean it does a lot of the lifting for you like other frameworks that might do more 'under the hood' (although it does quite a bit).

Collapse
 
andrewchou profile image
Andrew Chou

Do you work on React full-time? You seem so busy addressing people’s questions and complaints on Twitter 😅

Collapse
 
dan_abramov profile image
Dan Abramov

Yeah, I work on React full-time. I suppose engaging with community can be considered a part of it although I mostly do it because I enjoy that, and it doesn’t take that much time to shoot a few tweets back.