I've been working on learning React, and finding it particularly difficult. It appears there are a large number of things I need to have in place and pieces of knowledge I need before I can use it. These include some kind of Js compilation step like Webpack or Browserfy, something like Babel, a knowledge of how to use ES6, an understanding of React, and an understanding of how to use React-Router.
Although I've done some Javascript on the front end, I haven't done the other things I mentioned. The tutorials all seem to assume I know how to do everything but one little piece of detail, and I'm finding it difficult to bite on the elephant. It's hard to tell where to start on learning this stuff, and how much I need to learn before I can use it.
Any suggestions for what resources and approach to use to learn react? My goal eventually is an app that runs in 3 versions: web, iOS, android. I don't intend to use javascript on the server.
It assumes very little and builds an app from the ground up, including configuring Webpack, Babel, react-router etc, explaining what it's doing along the way.
It does use Javascript for the server, but it's well abstracted so it's clear where to swap out the server if needed. (I actually skipped over the server part of the tutorial on the first run through and it didn't hurt my comprehension.)
Start with an HTML boilerplate which takes care of the details of transpiling (which are initially irrelevant to you in learning mode). My first react app started out in a file like this [1] and I didn't go and figure out how to set up a build or use ES6 features until I was > 1000 lines into it, with a working prototype.
If you have an idea for something you want to build as a learning experience, following the same flow as Thinking In React [2] is a good way to get started, using the docs as a reference as you start to explore each area.
- Start by writing a single component which implements render() to get a feel for using JSX.
- Then pass some props into it to get a feel for working with those and interpolating JS using {}.
- Then create a second component and use it from the first component's render() via JSX.
- Once you've done that, you should have enough knowledge to create a static prototype of whatever you want to build while learning and you can play about with componentisation as you go.
- Once you have a static prototype, you can start to learn about state and pass callbacks to child components when they need to update state held somewhere above them.
Just do the simplest thing to get it working until you understand what's going on with props and state. Don't jump straight into React Router, as you'd be missing a chance to learn about, for example, state (to control the current page), conditional rendering (to display whatever should be the current page component based on state) and component lifecycle hooks (to register a basic hashchange event handler to implement your own simple back/forward support). Don't jump straight into Redux, Flux or a cursor implementation, as you won't get a chance to experience the problems they solve first-hand. Build up your app's complexity gradually and come back to these things later once you feel like you have a handle on things.
When someone is looking at something in the app, I need them to be able to paste a link to someone else, and have the recipient see the same thing. Sounds like a job for react-router, right?
I'll start off by stating that I am not a frontend dev, but I've been trying to learn React to connect it to a backend API and I too find it difficult for the same reasons you stated plus some others:
- The FB React docs are a bit scattered in terms of content and not as intuitive / helpful for a beginner as I'd hope they be
- I often resort to referencing other people's code from Github, StackOverflow & Google and the mix of ES5,6 & 7 styling used is hard to wrap my head around, especially when I try to find a source of "truth" on how to adopt the more idiomatic way of doing things seeing how everyone is using a different version from docs to examples
- React-Router's docs & code samples vary widely from what they state in the repo vs what people are actually using, and the whole pre 1.0 / post 1.0 way of using it has bitten me more times than I care to count - this is most likely me jumping in at a transformative time in the project
- Learning tools like webpack, browserify, babel, gulp etc. have been nothing short of a learning curve and these tools are basically required to be useful in React without repeating yourself from running commands over & over again when developing
- I've learned Flux's architecture, understand the concept, have integrated its structure into my code and know that this is the proper decoupling required, but its definitely not been an easy process for me to have to think about how I need to modify the flux pipeline for new functionality and how I can cut down on repetitive code.
- I don't understand how to manage state properly when I navigate to another page - this creates issues for me around the combination of flux + react-router as my lack of experience with them as well as lack of proper examples to utilize make the two difficult to address some of the state management issues I encounter. i.e. If a user logs in & they have a token, do I make use of local storage, do I not, how do I navigate to another page seamlessly with information I want to pre-specify such as the fact that a user is logged in and some of their basic info so I dont have to hit an API etc.
- Lastly, I fear committing to an all-in javascript-dependent solution for a frontend will segment users in terms of it working or not - see http://maketea.co.uk/2014/03/05/building-robust-web-apps-wit... for the tidbit about how SquareSpace's page is completely blank if javascript is disabled - this worries me that I may have a user that can't even interact with my page either because they disabled javascript, or because their browser is outdated/lacks expected functionality.
I know most of these issues stem from my lack of exposure and knowledge in this frontend endeavour. Nevertheless, I have to assume others are getting bit by many of the same issues as well and I constantly question if I'm biting off more than I can chew with React, as well as if I should just go back to the more traditional way of doing things on the server-side which I happen to know & understand already.
To your last fear... we're using a noscript > meta element combination to refresh/replace to a noscript.html page for users without JS... same for old Ie (conditional comment) for that matter.
Higher in the thread there's a reference to a Full Stack Redux Totorial that looks really good so far, only skimmed it... as a starter point.
Your state is best as one big state tree passed through components as props... your events/dispatchers can then trigger requests to load from stores... these stores then signal when data is loaded, which can trigger an update to state, which causes an update/render to your ui. The Redux workflow is a distillation of the flux framework overall, and might be an easier place to start, and stay with.
As for local storage, your stores can use local/session storage to save information locally for requests... for that matter, you could save your current state to session storage in case of a reload/refresh, etc.
As for router... not all SPAs need to change routing... It makes it a bit more complicated, and your stores can/should be your interaction with data that may be available locally or via server.
It's probably a good time to start looking at using the Fetch API [1] for making AJAX requests instead of using jQuery or Backbone (or even XMLHttpRequest). Support seems to be growing quickly and Github's polyfill [2] can help cover the gaps.
Agreed... I really have come to like fetch, though I usually wrap it in a couple functions for my most common use cases... since some of the options are a little tedious to specify over and over again... such as `postJson(url, data)` which will post the data as json, and resolve the json response with some extra error handling.
It works well, and combined with babel for async/await, the workflow is pretty smooth as well.
I think the implication is not that jQuery is bad for DOM manipulation, but that you should leave DOM manipulation to React to have a 1:1 relation between the held state in React and the actual DOM. In other words: Do not manipulate the DOM outside of React.
This is a React style guide; which implies that React does all (if not, most) of the DOM manipulations for you. jQuery, as a library, have useful utilities that that do not do DOM manipulations.
I use Backbone models for ajax since it makes decisions such as PUT vs POST and model.save() looks cleaner than $.ajax. Also, Backbone collections provide a declarative way to handle sorting and duplicate models. But these models are internal to the Store and not exposed to the views. I'm still a React newbie. Is this a valid reason to continue using Backbone?
1. If you're not passing the backbone models to React components, this sounds fine. backbone models as props ends up being really painful because of how mutable they are, and when we tried to manage that with mixins, it was buggy and caused problems (note: I'm not familiar with the actual mixin we used there and whether there was a better way to do it). Since most flux implementations are pretty stateful/mutable themselves, using mutable backbone models there, so long as you copy data out to pass to react views, seems safe. Though I'm excited long-term about the immutable flux implementations (https://github.com/rackt/redux)
2. We had a library originally written by Ben Alpert (now core react team) that handles all of our interactive svgs [1]. Since KA has a lot of legacy code there, and there hasn't been an immediate benefit to porting it (which would take a pretty significant time investment, on the [very roughly] order of a couple dev-months), this is still mutable jQuery/raphael code. There have been a lot of talks of eventually porting this to react, but the immediate need for it hasn't been there yet. However, I did write a React wrapper around much of this code which is used by newer interactive widgets [2].
Its a good and common question. Backbone can handle rectangular models okay. When you get into more complicated UI states, or if you have two different views backed by the same ui state like here [1], backbone models totally fall apart - backbone model is designed for list-of-records where the list can change or a record can change, it can't elegantly handle other shapes, like nested records, or list-of-lists, or tree-like (recursive comments), whatever arbitrary shape most naturally models the domain.
Backbone models are also mutable which means lots of model change listeners (callback soup) - check out the flame charts here [2] to get an intuition for what callback soup does to your code and how react fixes it.
I would argue that's fair. Somebody might come along and suggest you GraphQL all the things, but the flux-flavors mostly tend to be focused more on the use of state in applications and less so across the wire. And Backbone's collection/model is pretty good at that.
I can see argument against adding heft to your app, though - if that's something you're worried about. There's the ampersand library which tries to be more modular while reflecting the good parts of Backbone, but it seems to be going a bit quiet.
>> So you never expose your models at all to your components?
Yes, I don't expose models to the components. I'm trying this on a side project. We are still using plain Backbone in production. So, I don't have experience with large scale React apps.
>> What other benefits could Backbone models have?
It also features like validation and other stuff like nested models built by the community.
>> How do you expose your models to the view, I would guess you just serialise into regular objects?
I'm curious why the top is preferred over the bottom:
Open elements on the same line.
The 80-character line limit is a bit tight, so we opt to conserve the extra 4.
Yes:
return <div>
...
</div>;
No:
// "div" is not on the same line as "return"
return (
<div>
...
</div>
);
The latter I feel is much more readable and clear than the former, as it has a certain symmetry and cohesion that you find in normal html. The top one seems to be break readability. Wondering if anyone can comment on this specific decision?
Their logic is that because elements are typically deeply nested, it's better to sacrifice the readability for the saved indentation. By the time you get 4 child elements deep, almost half your line space goes to tabs.
I thought so too. I guess this is a good time to remind ourselves that we are not our work and it's best not to be too attached to the things we create.
It's worth noting however that the heading says to minimize jQuery and more specifically jQuery plugins. My guess is that jQuery is fine as long as it's serving a low-level function (XHR, etc).
Not sure how much I agree there... I think the goal is to get away from kitchen sink libraries, react's rendering flow allows for an interaction style that doesn't typically need something like jQuery...
For that matter, I'm surprised they don't have standard polyfills that include fetch, which combined with babel (async/await ftw) make your workflows much easier to reason with.
Style question re dom manipulation: third party embeds, such as twitter, instagram often come as specially classed blockquote elements that are swapped with iframes by a jquery plugin. What is the best way to integrate this with react?
"Fit them all on the same line if you can." (HTML Properties) -- OK, easy enough, my editor has no limit on its line length. I can always fit them on one line. Or did they expect it to fit on one line visually. If so, at what width to they expect my editor window to be?
In all seriousness, though, I appreciate the brevity of this guide. It can be quickly read and understood, and is not the fully-fledged book I've seen from other places.
Yes, the "In all seriousness" phrase was intended to let you know I was joking. I knew what they meant, even if they didn't explicitly say it on that line.
A number of these guidelines reinforce my biggest complaint with React: it is architecturally difficult to avoid monolithic view files.
In a traditional web app, we have 4 layers: client views, client app, server app, database. React, described as a strict view layer, in reality is being used as much more. At this point, it is not just consuming the client app, but is also taking nibbles at the server app as well.
To each their own of course, but i would ask people to hesitate about these decisions. The architectural issues with monolithic views is well known, and just because we have a shiny new tool does not mean we should throw that understanding by the wayside.
Source: i work full-time on a React and Backbone app
Can you explain what you mean a bit more? My experience with React is that composing components is so trivial (particularly compared to e.g. Angular directives) that I've tended to end up with very small view files (~10 lines of DOM max, plus whatever functionality is directly tied to that). It's seemed like one of React's greatest strengths to me, so I'm curious as to where your complaint stems from.
(I don't use React in my day job... yet. But I'm considering pushing for it, so getting a better understanding of its shortcomings is really important to me.)
I think it might be an objection to what the style guide refers to as "logic components": components that use React's `setState` to handle interactions and decide what props to forward to a "presentation component".
Personally, I feel that React is a handy tool for both of these use cases, but the fact that we're finding these two distinct types of components suggests to me that React's "component" abstraction might be doing too much.
Maybe if we break React into the pieces that are helpful for "logic" and the pieces that are helpful for "presentation" we'll end up with two abstractions that are each better suited to their task.
React's ideology is still very young, so I'm hopeful that the community will start to head in this direction, and I'm super excited to see how this plays out :)
Yeah, I really dig those :D The concept of a "presentation component" has the exact same semantics as a pure function, so I'm excited that we're actually gonna get that abstraction.
The part that concerns me, though, is the logic component. Hierarchical state/event management seems like a hard problem, and React does it okay, but a lot of things end up coupled together: why does a component that manages a state hierarchy and event flow need to be coupled to the idea of rendering a virtual DOM tree? Can't I just declare that my TodoApp state is a composition of my TodoList state and TodoForm state without also declaring how I'll eventually render them?
I wonder if anyone's come up with a really great abstraction for this yet that checks all the boxes. I like the philosophy behind how Redux manages state, but React provides clearer encapsulation of state and doesn't make parent components think about the events that their children are handling.
Redux is even crazy younger than React, though, so there's still plenty of room to grow there, too!
What do you mean by monolithic view files? It's pretty easy to separate at logic boundaries into smaller components...
As for universal rendering, using the same view engine on both the server and client makes sense. Not only that, but being able to use the same routing engine for client and server rendering, especially on a public facing application is a pretty nice thing as well.
It sounds to me like you are doing React development incorrectly. You should aim to break down your mockups into small components, preferably stateless components (introduced in React 0.14) and only have the higher level components act as wrappers that pass down data into the small stateless component leafs (which should be the majority of your UI).
We're trying to reduce the amount of JavaScript on our pages and have decided at this point to move forward with Redux as our common approach to state (keeping an eye on things like Relay and Falcor as we move along).
We are trying to remove Backbone from our codebase entirely.
This is more of a guideline for their particular organization -- they've decided to move away from Backbone and don't want developers adding any new Backbone code.
Correct. That and passing mutable backbone models as props went poorly back when we did more of that. Mutable props are hard to reason about and go against all of the recommendations for React props. (There are plenty of good use-cases of backbone out there though.)
It makes me feel so sad that the "state of the art" in front-end development is apparently rerunning your render code on every little update. Yes, I know there are shortcuts to making this more efficient, but in essence the technique remains inelegant in the sense that it does not extend well to other parts of the code (that runs computations that might also partially, and not fully, change on an update).
I think you will find that it does extend well to other parts of your code. Code that is idempotent allows you to reason much more effectively about what it will do. It always does the same thing and does not introduce side effects. It also allows you to test it much more easily. In fact, doing computations is one of the places where being idempotent will really clean up your code.
It may seem like a new fangled idea, but actually it has been around for quite a long time. It's just that it didn't really get out of academia and the few shops doing functional programming until lately.
Not to mention idempotent code is trivially memoized, allowing you to skip computations you couldn't previously reason about. A function that produces a value is always comparable to another value — a function that modifies some state requires that you have a way to observe that the world changed in order to skip doing it again.
This pattern of the virtual DOM has some parallels with functional programming. At first look, using functional programming it looks like you're sacrificing the performance that you gain from mutations -- which to some extent is true. But when you look deeper, you'll find that the data structures for functional programming languages have been adapted to work in a very performant way with functional programming patterns.
In the same way, when you look closer at the virtual DOM model, you'll find that you can optimize the usage very well. For example, when you use React with immutable data structures (e.g., Immutable JS), deep equality comparisons can be done very quickly to reduce renders to the minimum subtree required, and to issue the renders for a given change in a batch operation.
With React, you often end up with even faster code than using manual DOM manipulations. Of course, your performance will vary depending on how you implement your code. Depending on which model you're using, and how you program, you may end up with a faster or slower product with either methodology.
But at the end of the day, the performance gain from running code using state mutations just doesn't seem worth the effort of having a significantly harder time reasoning about the code, and having to deal with the challenges of scaling a project where the complexity grows much faster with each line of logic.
And my feeling is that due to the time invested in managing a more complex project that deals with mutations, the "performance per engineering hour" gained for projects using a virtual DOM is more favorable for many projects.
I think the main problem with your argument is that you assume that the world looks like a shallow tree. For UIs this may be, to a great extent, true. But for non-frontend code, the world looks more like a deep DAG (directed acyclic graph).
Also, suppose I have a list of thousands of elements. Now suppose one element is added to the list. React will still perform a comparison operation on all of those thousands of elements.
That's going to be a problem regardless. You shouldn't have so many elements on one page (can a user even parse through so many at once?). Use pagination or occlusion culling to show a few at a time instead.
Premature optimization is the root of all evil. Using immutable objects means that the overhead for checking a component that has not changed what it's rendering is a couple of function calls plus an object identity check. Modern JS can do that very, very fast.
And, if you find that it's still too slow, there are other strategies you can employ to fix it without having to turn your whole application into a stateful soup. Odds are, though, that this is not going to be your bottleneck.
Eh, kind of. If you're rendering, for example, a Table with a lot of TableRows and change one of the values in the data array being passed to Table.props, you'd return true from Table.shouldComponentUpdate, and then each child TableRow would need to run its shouldComponentUpdate, even though only a single one really needs to update. So the argument is GP is making is that it's more efficient to directly update that single DOM element rather than update the data and then perform the calculations to determine that we need to update that single DOM element.
True in theory, but as long as each TableRow implements the PureRenderMixin and the Table render itself is efficient, you're going to need a lot more than a thousand rows before React has any trouble hitting 60fps in my experience.
But if you can't meet both those conditions, that sort of thing definitely can get quite slow.
Are modern CPUs really going to choke on a few thousand comparisons?
My impression has always been that, for any constant-time operation, you're gonna need to start getting into the 100Ks or even the millions to start noticing, but I don't have the data to back me up here :/
React is okay for normal form based stuff, but it breaks down very quickly with many (<200ms) renders.
I like the abstraction, it is super easy, has a small API surface and most of the time it is "fast enough". But it's no panacea. Often I have to throw D3 in, to get "realtime" stuff done without blowing up the browser.
> That's actually what I love about react apart form using hierarchal components as building blocks.
This is interesting to me - I've become a bit wary of the hierarchy of responsibility as well.
Seems like a lot of it is stemming from the fact that there certainly is a hierarchy within the DOM. (This is one of the reasons I was so excited about GSS, which gives the ability to build a flat dom). But what are the solutions otherwise?
Yup, but it's important to know that the building blocks in JSX isn't the actual DOM, it's some sort of a descriptive explanation of it. That's what's being used to diff.
Hand-written code will always beat a framework; React isn't trying to be faster than domain-aware DOM manipulation.
Instead, React seeks to be the state of the art in maintainable view architecture. One of its secondary goals is non-sucky performance, which it does pretty well.
Most devs aren't working on apps where React is the performance bottleneck. If you are, then, well, don't use React.
I would love to read more about styling inline and completely remove external CSS files.
Are there any CSS-frameworks that have been converted to JS but not are not their own components yet? It's easy to find React-Bootstrap but that comes with ready made components, I am looking for styling that's purely in JS so I can make my own components.
Also would a route-component be considered logic or presentation, or maybe it is its own thing and they forgot to mention it?
I don't like inlining styles as objects in React so I went looking for a solution that would work with the toolchain I'm using for my current project.
I'm working on a project now that is using a combination of react-css-modules, webpack, and an ExtractText plugin for webpack that means each React component I write can have an associated CSS file.
Each class in the CSS file gets mangled so that it doesn't affect things globally by react-css-modules. Then the ExtractText plugin for webpack pulls all those CSS files out into one, global styles.css file.
Ultimately, that means that my CSS file might actually, over the life of the project, shrink! Unheard of.
In the same project I'm using redux and redux-router. The router consists of declarative components, like "<ReduxRouter />" and "<Route />".
We're playing around with inline-styling our components, but pushing the inline-styles into CSS injected into `<style>` tags in the head. It's experimental at the moment, but it's being sent into production shortly: https://github.com/Khan/aphrodite
I'm not exactly sure what you're asking for, but I'll try to answer anyways. http://material-ui.com/ is a React component library that uses inline CSS exclusively.
Although I've done some Javascript on the front end, I haven't done the other things I mentioned. The tutorials all seem to assume I know how to do everything but one little piece of detail, and I'm finding it difficult to bite on the elephant. It's hard to tell where to start on learning this stuff, and how much I need to learn before I can use it.
Any suggestions for what resources and approach to use to learn react? My goal eventually is an app that runs in 3 versions: web, iOS, android. I don't intend to use javascript on the server.