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:
- One question per comment.
- The questions have to be about React.
- No question is too simple! Seriously, ask away, I don’t bite.
- 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.
- 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)
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!
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
orReact.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.
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!
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
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.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.
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.
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 🙂
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.
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.
Thanks for the answer :)
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 withprops
andstate
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.
Oooh acync rendering and compilation both seem exciting.
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.
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:
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 insideshouldComponentUpdate
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.^^ I agree with this. I’d also note you probably want to use
PureComponent
when you optimize instead of manually writingshouldComponentUpdate
. 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 ashouldComponentUpdate
but not verify that it actually bails out when expected.Thank you for your answer Dan. I am definitely going to consider using PureComponent instead of shouldComponentUpdate, if I need it of course.
I'm provably misunderstanding something when you said:
Why should B not update? Is this what you meant? codesandbox.io/s/ol4zllpj19
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 :)
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.
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...
Thank you for the clarification Dan.
Here goes another one: what would you recommend as initial steps to participate in React as open-source collaborator?
Thanks again!
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!
Awesome! Thanks, will do.
Welcome Dan, definitely a lot of React folks happy to have you around.
This definitely jives with the reason we're here in the first place.
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?
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. 🙂
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.
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
orenzyme
. It is up to you to decide how to balance unit tests with integration and snapshot tests in your app.Thanks for the rapid response in the Christmas day! Another question regarding HOC. How HOC is different from decorator design pattern?
I guess it’s a React-specific variation on it?
Probably :) but I can't really confirm since I have not used HOC in depth.
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.
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.That’s a great point, you actually can test interactions with multiple snapshots.