10 ms·
React JS Best Practices
- lopatin 11y agoAuthor here, happy to answer any questions or discuss further!
- nulltype 11y agoIn the article you say you "Reuse through React instead of CSS" and that you have CSS files for the components and no global CSS classes. Do you mean that the CSS files are applied to the elements as inline styles by react, or just that each component has its own CSS so it's not really "global"?
- lopatin 11y agoThe latter. Most of our components have an associated scss file. I didn't consider those to be global because we namespace all css rules in the style files under a class name of the same name as the component. But that's a great point, it didn't occur to me that that paragraph may have only made sense to people familiar with our conventions.
- nodejsisbest 11y agoThis is a, well, dick off account but behind it is really a genuine developer. I recently converted my React code from scss to the embedded styles in JavaScript. Does each component have that many scss styles to justify using scss? I guess my project isn't such a large scale, but I'm just curious as to what benefit you get from scss. Note that I didn't read the article. I rarely do, but I'll give this one a go because well, I'm commenting on the gosh darn thing so I may as well stop being a fucktard and read the damn thing! EDIT: Well, you only mention scss once in the entire article. I guess I didn't learn much on why you use it vs. just using the embedded styles for components in React.
- rattray 11y agoInteresting. Asking out of curiosity, not skepticism: why not use react styles in js directly, à la vjeux et al? Reasons I'd guess: not being able to use pseudo-selectors and things like :hover; familiarity for designers; easier use of legacy code; benefits of SCSS that would take work to re-implement in js. But I'm curious what your real reasons were!
- lopatin 11y agoThat's pretty much it! Although the ideas presented here do make sense (https://speakerdeck.com/vjeux/react-css-in-js https://speakerdeck.com/vjeux/react-css-in-js) we haven't gotten there yet. Our css namespacing scheme solves the "global namespace" issue, which was the biggest issue that stood out for us.
- nulltype 11y agoI like the vjeux thing, I think for dynamic sites if we replace static html and css with javascript the world will be a better place.
- vanadium 11y agoGot a FOUC (especially on the webfonts) the first couple of renders on the page; looks like the overloading of the META tags might be to blame. Otherwise, really good stuff here as someone rapidly picking up on React.
- noahgrant 11y agoWere you looking at the siftscience.com marketing site or the Sift Science console?
- rektide 11y agoReact is supported by a ton of goodwill from a lot of camps. What you offer here seems like some particular experiences you had. To say it's a best practice because it explains your world feels to me laden with folly. Linking a particularly wishy-washy state v.s. props article in core docs as if it's the final gospel- reeks of finding easy convenient idols to call out that make you sound better- it sells your article with a notion of completeness, declares a kind of finality. Nearly every point raised comes to me more as a question, a thing we have some rough anecdotes to tell, rather than something actually informative or much less definitive. I'll just start walking down your article's core bullet points. Use componentShouldUpdate well: yes, do. You'll know why you should, quickly enough. State v.s. props is a great point, but then you need both declarative managed injection via props to initialize or control, mixed with a transient stateful interactivity when the user begins free interactions. Early experiments in "best practices" are efforts like React-Controllables, trying to create components which are isomorphic to state v.s. props driving them. Everyone is doing their own experiments with how and where data lives and how and where it gets there. That's the nature of webdev, experimenting with pipes. Some cursory words on Flux in your article indicate how vastly unresolved and mysterious the ???->data part of the webapp equation is. "We're experimenting with something Relay like". So way Soundcloud in 2012. Best practice: use react for the next step, data->html. Best practice: wrap the most boring boilerplate css with your own react components. Oh great, just what everyone needs to go do. Recommendation is to not rely a lot on css, but how, if not global, do we start sharing some style rules effectively? It's disingenuous to offer this as settled "be balanced" best practice, particularly when it's still the hay days of excitement, with new encompassing visions like https://github.com/petehunt/jsxstyle/ https://github.com/petehunt/jsxstyle/ just popping up.
- lopatin 11y agoIt looks like you're bucketing the ideas in the post into one of two categories. Either 1. Too obvious to write about or 2. Not a best practice because new ideas are always being introduced. Regarding the first, those topics weren't obvious to everyone. Besides no one really benefits when posts are called out for this. And re the second, these patterns have emerged from one year of maintaining a large app with a growing team. The points mentioned are tips for writing code so that your app will scale, not silver bullets for complex topics such as the general question how to write styles for React. The best practices mentioned in the post are just that, but they're not the only ones.
- nthitz 11y agoHi, how does React work with other libraries that modify DOM state arbitrarily? How might d3 dom changes or canvas context calls work with React
- lopatin 11y agoNice, we're actually posting a tutorial in a week or two about how we use d3 + react. I'll try to summarize though. In the case that a library modifies the DOM, we try to keep React out of it's way. React works best when it has full control of the DOM. In these cases, React components are more of "wrappers" for the 3rd party libraries. Mostly by using the componentDidMount/componentWillUnmount to initialize/destroy the third party library, respectively. And props as a way of giving the parent a way of customizing the behavior of the third party library that the child wraps.
- lobster_johnson 11y agoWe use Google ads in our React apps, and it turns out to be a problem. I wonder if anyone has solved it in a satisfactory way. Basically, with GPT you have named slots identified by their DOM element IDs. You can "refresh" a slot any time, which will populate the element if it's empty, or load a different ad. So we do that when we're mounted. Unfortunately, if the page structure changes, React will re-render the component and blow away the contents -- anything GPT has put in the element is considered alien. That's fine, we just refresh. The problem is knowing _when_ a render has finished and the ad element is empty. In my testing, React elements would often have a delay after which their changes have been applied to the DOM; so I use setInterval to check repeatedly for an empty element. It seems like a stupid solution, but I couldn't figure out a more solid way; there's no React callback for completed renders.
- dandelany 11y agoSeems to me you could wrap ad elements in container components that have: shouldComponentUpdate() { return false; } Which would prevent React from re-rendering them after initial mount... any reason why this doesn't work? I do this often when using d3 selections to keep React out of the way and catch incoming props in componentWillReceiveProps instead.
- rattray 11y agoGreat article, thanks for sharing! Would have loved a few code samples to go along but your descriptions did an impressive job describing what's going on. One question: what does that "global Backbone cache" look like?
- lopatin 11y agoThanks! Glad to hear it was easy to follow and didn't ramble. Our backbone model cache is a simple module that you request backbone model instances from by a unique key. You also pass initialization options in case it doesn't exist in the cache. The instance will be constructed, saved in the cache, and returned. You can pass a TTL also. It's not great, feels clunky, but it works.
- UUMMUU 11y agoI noticed in your first code example you use a mixture of leading a method with an _ and some without. Ex. navigateToContact vs _hasUnsavedChanges and _saveChanges. I read somewhere that a best practice is to always prefix custom methods with _ to differentiate from React core methods. What're your feelings on that?
- lopatin 11y agoOh this is definitely a personal preference thing, but our convention is this: private instance methods start with an underscore, public instance methods have no underscore. Public ones have no syntactic difference from the core life cycle methods but that's ok to me because they're all easy to remember. Btw we use public instance methods very sparingly, basically as a last resort when all else fails.
- UUMMUU 11y agoAwesome. Thanks again for the write up. I love reading well written Javascript.
- nulltype 11y agoI've been looking at reactive UI design, and it seems weird to me that React.js has this React.createClass and .setState stuff. It seems like it would be better to let the user manage the state and just re-render whenever the state changes. Am I missing something about how this works that makes those necessary?
- Swizec 11y agoBy making it explicit and a bit clunky, you discourage users from using state. Without explicit functions to be called, you can't detect state changes and would need polling. This is terrible. At the end of the day, it's a limitation of JavaScript because unlike with Python, for example, you can't have automagic getter/setter functions. They have to be called as functions.
- nulltype 11y agoSeems like .observe() would fix that polling thing, right? http://www.html5rocks.com/en/tutorials/es7/observe/ http://www.html5rocks.com/en/tutorials/es7/observe/ Also you could just re-render whenever any event happens, which is probably when your state changes anyway.
- Swizec 11y agoIt would if browsers supported it: http://caniuse.com/#search=observe http://caniuse.com/#search=observe So far exists only on Chrome and Android browsers.
- lopatin 11y agoOne reason for the explicit method may be that React does an internal optimization where it batches state updates together. Two calls to setState can result in just one render. https://groups.google.com/forum/#!msg/reactjs/R61kPjs-yXE/ysmpC0IvA4YJ https://groups.google.com/forum/#!msg/reactjs/R61kPjs-yXE/ys...
- masklinn 11y ago
- supercoder 11y agoHaving just started using React for a new project, I absolutely love it. This new project uses a Rails backend, with React allowing the web to act the same way as any other client (iOS app, Android app etc), and it's so productive to work in. Pretty much decided I won't be writing a web app any other way for any future work. These best practices look pretty good, though my advice to any beginners would be to not get too bogged down in worrying whether you're doing things 100% right as React can be pretty forgiving in refactoring later on.
- rattray 11y agoI would love to see their HoverCard and similar components open-sourced, or at least shared in a gist. Many of their abstractions sound great & generalizable.
- pbowyer 11y agoOpen sourcing a library of components would be fantastic.
- girvo 11y ago> Flux is also quite verbose, which makes it inconvenient for data state, state that is persisted to the server. We felt the same way, until we moved away from Facebook's Flux implementation and adopted Flummox[0]. It's singleton-free, so we gained isomorphism for our application with only a tiny bit of extra work, and it hides away the dispatcher (unless you need it, which we haven't despite having over a dozen stores, tonnes of actions and a large number of components). With Flummox making it so easy, we put all state into a store. This allows us to save application UI state to localStorage, bootstrapping the app into the same position the user was previous, with again no extra effort on our behalf. It's well worth checking out! [0] http://acdlite.github.io/flummox/ http://acdlite.github.io/flummox/
- modarts 11y agoFlummox is incredible, and pretty much the first thing I point beginners to after they've learned the basic concepts of flux (I don't even show them Facebook's implementation because it's actually pretty poor and relies heavily on singletons and interacting directly with things that should be implementation details like the dispatcher)
- girvo 11y agoGosh yes, Facebooks implementation doesn't really do the whole idea justice to be honest. Alt and Flummox are much nicer, but I found Flummox far easier to use; one of the few libraries that seems to strike the balance between minimalism and features. I'm definitely impressed, and it was a super easy sell at work to move to a "three tier" architecture, because two of those tiers are the same code base with Flummox and React!
- garthk 11y agoWe rolled our own Flux library before they published any code, dodging singletons and gaining mock-free testability. I just re-wrote it, but will check Flummox out.
- agmcleod 11y agoI had been using reflux when trying out react native. This actually looks nicer than reflux, i think i'll check it out :)
- iyn 11y agoOne of my initial problems with React & CSS was styling :hover etc. For now, Radium [0][1] solves this problem, but IMO as a community we're still trying to figure out all the best practices and patterns, when it comes to building isomorphic webapps (or webapps is general, since React introduces new way of building apps and I'm sure that's just the beginning). [0] http://projects.formidablelabs.com/radium/ http://projects.formidablelabs.com/radium/ [1] https://github.com/FormidableLabs/radium https://github.com/FormidableLabs/radium
- pbowyer 11y agoWhy did you want to do it this way, rather than using CSS classes and a stylesheet? I've read the Radium intro and I still don't get their use-case. To me it feels like a misunderstanding of CSS, so inlining it in the component makes sense to the programmer.
- iyn 11y agoThis is a great question, I used to think exactly the same until I became enlighten ;). Well OK, to be honest I'm still not entirely happy with how things are modularized, but I see advantages. This is a very good presentation which explains key ideas: https://speakerdeck.com/vjeux/react-css-in-js https://speakerdeck.com/vjeux/react-css-in-js Understanding the problems mentioned in the slides was literally eye opening. I was already trying to solve the problems with CSS, without fully realizing that I'm solving them. For example, my "solution" to namespaces was creating a naming conventions for all classes/IDs, like ".header-search-box-button" and this approach becomes PITA quickly. Also, after a while I had more and more dead code, which wasn't easy to identify and I couldn't be sure that if I remove some class, I don't have any elements that depend on it. Non-deterministic resolution was also an issue for me - say user was on a page A (therefore had loaded A.css with class .main-button) where particular boxes are blue. If the user goes to page B (we load B.css which also has .main-button) he should have red boxes. But if the user gets back to page A, the boxes that are supposed to be blue are red (browser cached the style and when browser have 2 classes definitions, the one that was loaded the last "wins"). Sure, we could use IDs for everything, bundle all styles into 1 file etc., but bigger sites would have like 5MB CSS file and at the end of the day it's still hard to maintain the codebase. I'm sure that "normal" way works for regular/medium sites (it worked for a few good years, right?), but I see ton of advantages for using the inline styles in the JS. It's not easy to "convert" to new approach, but I honestly don't look back. As I've said - it's not ideal solution, but a very important step forward. This is a good 3-part tutorial on react, flux and some other things: https://www.youtube.com/watch?v=Pd6Ub7Ju2RM https://www.youtube.com/watch?v=Pd6Ub7Ju2RM https://www.youtube.com/watch?v=iR22EWW-CVc https://www.youtube.com/watch?v=iR22EWW-CVc https://www.youtube.com/watch?v=6fhTawDEE9k https://www.youtube.com/watch?v=6fhTawDEE9k
- revskill 11y agoI've wrtitten a book to show how to integrate Rails with React.js. It uses Backbone to act as Router. You can try it at https://www.gitbook.com/book/checkraiser/rails-and-react-js/details https://www.gitbook.com/book/checkraiser/rails-and-react-js/...
- perrywky 11y agoSuggestion: do not change any ui in any event handlers, otherwise you are doing it wrong
- OnlineRevenge 11y ago"I missed my ex bad. My family and friends were tired of me being so upset one of them actually ordered a Love Spell for me From Extreme Spells I had no idea what they had done. They ordered the GLOBAL LOVE SPELL as it your best and most powerful and effective Love Spell. Needless to say, I was shocked to see my wife at the door a week later with her eyes full of tears, .I cannot believe how well my spell worked. I recently ordered a Money Spell because who doesn't need extra money?" quickrevengespell@yahoo.com -- William, Nashville