Settings

Theme

React Tips and Best Practices

aeflash.com

253 points by grandpa 11 years ago · 41 comments

Reader

themgt 11 years ago

One of the things I didn't realize at first was the degree to which Relay/GraphQL appear to effectively replace a lot of Flux: http://facebook.github.io/react/blog/2015/02/20/introducing-...

Learning Flux sort of seems like learning how to drive stick shift on an '97 Civic while we wait for the new Tesla to arrive - useful, also a bit annoying. A central store architecture does seem a better match to what Relay will look like though.

  • post- 11 years ago

    I think one thing that's misunderstood about Flux is the store <-> model distinction. Coming from MVC, it's a pretty easy mistake to make, but stores _are_ effectively global state objects: You can access a store's state from any component -- whether that's good practice is doubtful, but it can be done -- and even though you have to call that store's getter in particular, it's not really that different from requesting state from a global object. (As the article hints at, Om makes it even clearer that stores handle global state in the app-state atom.)

    All of that is to say that I think Flux-y architectures can help with reasoning about GraphQL's and Relay's data handling, which I think is seconding your opinion, even if it's quibbling a bit with how annoying driving stick (or working in Flux) is. :)

  • chromedude 11 years ago

    That was my initial thoughts when Relay/GraphQL were announced, but it seems that though Relay is inspired by Flux it is somewhat different. Facebook's most recent post on Relay and GraphQL (http://facebook.github.io/react/blog/2015/02/20/introducing-... - February 20) addresses Relay's relation to Flux at the end and mentions that Facebook actually has apps using Flux and Relay.

  • picardo 11 years ago

    Don't forget that Relay means replacing your RESTful routes. If you still want to work with RESTful endpoints, you are going to work with Flux.

    • grandalf 11 years ago

      Exactly -- nobody (yet) has written any kind of general purpose mapping from rest concepts to relay endpoints. Relay appears to leverage graph db functionality/semantics pretty heavily.

      • jbhatab 11 years ago

        Pete hunt said it should be relatively easy to wire up a RESTful api to flux relay. And since mapping data to complex front ends is hard, but defining restful endpoints is easy, I'd rather design my database to be optimized for the complex front end scenarios. I imagine that you would be able to make a standard REST api from graphql.

  • danabramov 11 years ago

    I still think Flux will be handy for holding global UI state. Such as visible notifications, sidebar state, etc.

amelius 11 years ago

Let's be real. It's 2015 and we need quite some hoops to get, in most cases, some very simple data rendered on the screen. And even with all those hoops, we are still not sure that it works in all cases. Isn't it time for better tools than react? Like functional languages that support incremental computation?

  • lukev 11 years ago

    It's easy to speculate that better solutions are possible, but noone has ever actually done it. React (used from a more functional language, like ClojureScript) is the closest system to the world you describe which actually exists.

    And no, papers and toy proof-of-concepts don't count. They are extremely interesting, and a necessary first step, but someone needs to build something large and demonstrate effectiveness in the real world before you can make an honest bid for large-scale adoption. As far as I know, no other FRP or functional UI system has done any better than React on that front, yet.

    • amelius 11 years ago

      True. But consider this: if we had a functional-style language that did not do any incremental computation, only the minimal React-style of re-rendering, that would already be infinitely better. Because it would mean we wouldn't have to totally rewrite our code whenever incremental computation became a reality.

      In other words, we can do it in steps.

  • city41 11 years ago

    I recommend checking out ClojureScript. The community is really moving in this direction. I find cljs takes React from good to great (I wrote a simple blog post about that here [0]), and up and coming frameworks like reframe [1] are going to make it even better. reframe and even vanilla Reagent/Om/etc are heading in the direction you desire. ClojureScript still has some warts to iron out, but all in all I feel like it's our current best bet for some truly amazing apps in the browser.

    [0] -- http://www.mattgreer.org/articles/reagent-rocks/

    [1] -- https://github.com/Day8/re-frame

  • tptacek 11 years ago

    You should write an article or a blog post about that and submit it. I'd upvote it! This thread isn't a good place for your point, which isn't germane to the article.

  • eric_bullington 11 years ago

    It's a good point. But don't mistake Flux, GraphQL, cursors, etc. with React.

    React is just a great, fast way to interact with the DOM, with much less hoops than usual.

    I think the community is still converging toward the proper way to deal with state. First it was passing callbacks, then the Flux pattern, and now there's talk of how GraphQL and Relay fit in.

    And speaking of functional approaches, there are those of us who have been inspired by the Clojurescript community (who was in turn inspired by Haskell, as I understand it) and are interested in using cursors (similar to lens) to encapsulate state.

  • skybrian 11 years ago

    If you're interested in this, perhaps try Elm? I'm not sure about performance, but it does enforce a pure architecture with all state outside the render tree.

  • serve_yay 11 years ago

    It is always an adventure, to discover what will be on the other side of the phrase "Let's be real".

  • bpicolo 11 years ago

    Seeing "Mixins are awesome" is bringing back so many code smells. : (

  • warsheep 11 years ago

    Can you (or someone else) explain the need for the language to be functional?

    • city41 11 years ago

      I don't think there's a strict need, but functional languages tend to bring the desired traits: immutable data structures, referential transparency, isolating side effects and state mutation as much as possible, etc.

      It seems like the more one uses React, the more they crave the above, so it makes sense to use an environment where all of the above is natural.

lopatin 11 years ago

Great article. One thing I would like to mention is that using component state (this.setState) is okay! Central stores, and the flux architecture, are very helpful but if your state shouldn't persist after an unmount, there's no point in extracting to a central store and passing it through your entire app as props. (i.e. Whether or not a certain dropdown is expanded). Just keep that state local.

  • aeflash 11 years ago

    My point was that the state of the dropdown is something that perfectly fine to manage directly in the component (nothing else needs to know about it). Things like the selected value would not be something to manage using component state.

susi22 11 years ago

Has anybody in the client side community ever made the connection to rules engines? This flow of logic is awfully close to how a rule engine works. I wonder if people will at some point arrive at it.

There isn't a whole lot of rules engine in JS. Just nools [1] which is huge. I'd love to see a very simple forward chaining rule engine + Immutable + React and see how that would work out.

My guess is that they aren't popular at all because they have the notion of being enterprisey (Drools/Jboss). I'm a big fan of them. They /can/ make life & code very nice and elegant. Maybe somebody writes an JS adapter to clara rules [2].

[1] https://github.com/C2FO/nools

[2] https://github.com/rbrush/clara-rules

  • saosebastiao 11 years ago

    I see some similarities with a stateful recursive Rete implementation. I still wouldn't go so far as to say that it is basically a rules engine.

    The Rete algorithm (which is the underlying algorithm of most rule engines) trades off memory use for an O(1) execution time (where n==1 and n is the number of rules in the system). You really only gain any benefit once the number of rules grows significantly, and by then memory usage is significant enough that I wouldn't want it running in my browser. If I had a the need for a rule engine in the browser, I would invest most my effort on offloading rule processing to the server instead.

  • feider 11 years ago

    I'm not 100% sure what you mean by rule engines.

    I tried to use a FSM for a SPA that was developed with Backbone.js. First it was really useful, but it was really shitty to maintain(expanding etc), though that maybe was fault of implementation. Still it is interesting idea, that I might want to try again.

netcraft 11 years ago

What are the best resources for someone looking to learn react and jsx?

konstruktor 11 years ago

Alternatively, there is a very similar example, including a talk, right from the source: https://github.com/facebook/flux/tree/master/examples/flux-c... https://facebook.github.io/flux/docs/chat.html#content

nemothekid 11 years ago

With PureRenderMixin, doesn't that also prevent child components from updating in response to state changes? For example if a child component must update due to some event, but none of its parents care about that event, doesn't that cause the child not to update?

Edit: Turns out my render methods aren't pure. I query stores right render, which causes problems when using this mixin.

  • grrowl 11 years ago

    An often overlooked pattern in React is controller-views. When using Flux (or really, with any external-to-the-component data) you should put this Store logic in the nearest parent to the components who use it. This component is the "controller" which gets the data and passes it as properties to the child components (who pass it as required to their children down the hierarchy).

    This keeps your child components pure (fast, renders directly from props, uses PureRenderMixin) and keeps data access centralised to the nearest common controller-view component. It's okay to have a parent component that simply collects data to pass directly into a single child within the render() call — the parent fetches data and sets props, the child re-renders only when the props update, and there's a clear separation of responsibility between the two.

  • iirvine 11 years ago

    That's kind of the point, at least as I understand it. You want to minimize the number virtual nodes that need to be reconciled to actual DOM nodes. If nothing about a parent's props or state has changed, then ideally nothing should have to change about any of its children.

    http://facebook.github.io/react/docs/advanced-performance.ht... has the best description of this process I've found so far.

  • TheCoelacanth 11 years ago

    If you use PureRenderMixin, all child components must also be pure. If a pure component wants to change what it renders because of an event, it must change its state, otherwise it won't be re-rendered.

z5h 11 years ago

These are all excellent points that resonate strongly with my experiences with React. Thanks for the article.

piran 11 years ago

Data passed to the controller view should be state from stores, not props. read the docs plz.

  • aeflash 11 years ago

    That's only true if you're following the canonical Flux architecture to the letter. There's little difference between having your store trigger setState() on a root component and having your store trigger React.render(<RootComponent/>) with new props.

  • ramblerman 11 years ago

    If anything the docs reiterate (quite a few times) that this is one way, and not a golden bullet. And that flux is just one of the architectures you can use with react.

    But you certainly get the award for least imagination.

Keyboard Shortcuts

j
Next item
k
Previous item
o / Enter
Open selected item
?
Show this help
Esc
Close modal / clear selection