We're sorry but this page doesn't work properly without JavaScript enabled. Please enable it to continue.
Feedback

React.js on Rails

00:00

Formal Metadata

Title
React.js on Rails
Title of Series
Part Number
82
Number of Parts
94
Author
License
CC Attribution - ShareAlike 3.0 Unported:
You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal and non-commercial purpose as long as the work is attributed to the author in the manner specified by the author or licensor and the work or content is shared also in adapted form only under the conditions of this
Identifiers
Publisher
Release Date
Language

Content Metadata

Subject Area
Genre
Abstract
React is the best way to bring interactive UIs to your Rails apps. But using React.js on Rails can be hard. NPM libraries are difficult to include, JSX seems nonsensical, and “can we still use CoffeeScript?” There’s not one obvious path for working with React.js on Rails. In this talk, we’ll review the sordid past of Rails and JavaScript, explore the complementarity of React and Rails, and navigate the woes of integrating with NPM. We’ll discover why React is a natural fit for Rails today and how to make Rails love React in the future.
Multiplication signHecke operatorComputer animation
Product (business)MathematicsGoodness of fitPlastikkarteData managementSoftware frameworkProjective planeData structureMobile appState observerForm (programming)Cartesian coordinate systemSoftwareService (economics)Validity (statistics)State of matterView (database)Set (mathematics)Right angleEndliche ModelltheorieMultiplication signRevision controlTwitterTrailGame controllerProcess (computing)BitRouter (computing)Scripting languageArithmetic meanSelf-organizationOnline helpCurveClient (computing)Computer animation
Cartesian coordinate systemMobile appMereologyPlastikkarteRouter (computing)Computer animation
Projective planePoint (geometry)Product (business)Graphics tabletRight angleAutomatic differentiationBuildingRule of inferenceClient (computing)Computer animation
Transient stateMultiplication signMathematicsEvent horizonInteractive televisionServer (computing)Presentation of a groupoutputService (economics)Web pageReal-time operating systemTrailRight angleWireless LANGroup actionDependent and independent variablesGame controllerComputer animation
Web pageInteractive televisionBitConnectivity (graph theory)Cartesian coordinate systemReplication (computing)Process (computing)Real-time operating systemComputer animation
Software developerLogicCartesian coordinate systemTerm (mathematics)MIDIMultiplication signComputer animation
Connectivity (graph theory)User interfaceFacebookElectronic mailing listVolumenvisualisierungLibrary (computing)Local ringType theoryAbstractionComputer fileView (database)MereologyState of matterRight angleWordService (economics)Computer animation
IterationPartial derivativeCodeWindowConnectivity (graph theory)VolumenvisualisierungMereologyWordSign (mathematics)Particle systemRight angle
Hash functionVolumenvisualisierungSystem callSocial classMappingConnectivity (graph theory)Multiplication signLocal ringDifferent (Kate Ryan album)WindowIterationElectronic mailing listFunctional (mathematics)Right angleCategory of beingCodeGroup actionLogicFamilyBlock (periodic table)Computer animation
Mobile appBlogBlock (periodic table)Revision controlCASE <Informatik>Connectivity (graph theory)Functional (mathematics)VolumenvisualisierungSocial classNatural numberView (database)Graph (mathematics)Division (mathematics)Right angleFile viewerComputer animation
Block (periodic table)MappingFunctional (mathematics)VolumenvisualisierungSocial classEntire functionState observerMobile appMathematicsRight anglePlotterCellular automatonComputer animation
Real-time operating systemSingle-precision floating-point formatConnectivity (graph theory)2 (number)Functional (mathematics)HookingVolumenvisualisierungState of matterSpecial functionsSystem callMultiplication signObject (grammar)ResultantRight angleCASE <Informatik>Network topologyRule of inferenceGreatest elementDimensional analysisSource codeGame controllerGraph coloringInteractive televisionOrder (biology)Ocean currentComputer animation
MathematicsState of matterInsertion lossElectronic mailing listTouchscreenCodeDifferenz <Mathematik>View (database)Computer fileConnectivity (graph theory)Block (periodic table)Semiconductor memoryVolumenvisualisierungProcess (computing)QuicksortWordString (computer science)Food energySource code
NumberState of matterConnectivity (graph theory)Type theorySet (mathematics)Event horizonInitial value problemMessage passingMultiplication signString (computer science)Right angleDefault (computer science)Figurate numberSoftware developerService (economics)DigitizingWordDegree (graph theory)Computer animation
Table (information)Row (database)Service (economics)Mobile appRight angleMultiplication signCartesian coordinate systemSemiconductor memoryIteration
BitImplementationInstallation artConnectivity (graph theory)Repository (publishing)VolumenvisualisierungLibrary (computing)CodeType theoryMoment (mathematics)Mobile appDirectory serviceSource codeProjective planeMathematicsMereologyWeb browserProcess (computing)Formal languageGoodness of fitCore dumpRouter (computing)Point (geometry)Link (knot theory)WebsiteBlock (periodic table)CodePersonal digital assistantWordMultiplication signString (computer science)Computer animation
Connectivity (graph theory)Social classComputer fileBitError messageCategory of beingTemplate (C++)State of matterPoisson-Klammer1 (number)Right angleMereologyCuboidDifferent (Kate Ryan album)Constructor (object-oriented programming)Functional (mathematics)Escape characterType theoryImplementationSystem callFacebookFlagBacktrackingScripting languageCovering spaceSound effectDomain nameSet (mathematics)Slide ruleMultiplication signRepetitionReal numberGroup actionProcess (computing)MathematicsPreprocessorFlow separationPlanningComputer animation
Process (computing)Maxima and minimaMobile appPlanningPersonal identification numberComputer clusterView (database)Link (knot theory)Computer animation
Transcript: English(auto-generated)
All right, let's get this thing started. How the heck is everyone? I'm gonna need more than that, come on. How the heck is everybody?
Thank you, thank you. I think it makes me feel more comfortable. Thank you so much for coming to this humble little talk. I'm really glad that of all the talks out there you decided to come to this one. I'm feeling the feels right now. So in this talk we're gonna talk about JavaScript.
I feel like I won the lottery being able to talk about JavaScript at a Ruby conference. And I feel like it's one of those pieces of the Rails stack that's still just pretty terrible in general. And we have an opportunity to talk about how to make it a little bit better. But it's interesting, at this particular conference there's actually been a lot of talk about JavaScript.
I'm talking about like proper backpacks and like the zombie apocalypse, and whether or not JavaScript should be in your zombie apocalypse proper backpack. Try to say that five times fast. And so I wanted to tell you just about how we solved the JavaScript problem, or not how we solved it, but how we're using the right view framework
to help us write better Rails apps and better JavaScript on those Rails apps. My name is Michael Chan. Go by Chantastic on Twitter. And there's a much younger, happy version of me you might find there. So I work on an application called Services.
It was launched in 2006, and started on Rails 1.13. Services is an application for churches actually. It helps churches organize volunteers, their timelines, services, all that kind of stuff. It's pretty cool, and believe it or not there is actually a market for church software.
So I mean it started in 2006, so our approach to JavaScript has kind of been, yes, write it. And as you know, after a little bit of time, sprinkles tend to turn into mountains.
So we needed a way to better structure our JavaScript applications, right? So in 2012, when we were writing our second app, we started to kind of look at the landscape and see what people were doing. So we looked at bigger Rails shops, we looked at Shopify, and they were just starting to work on a project called Batman.js. Has anyone in here used Batman.js?
Oh, good for you guys. Or good for y'all. Yeah, so anyway, so we did this, and it was really interesting. I mean it had all of the kind of markers of a 2012 JavaScript framework. It was a two-way binding,
and you'd set up a whole bunch of observers to kind of track state and update things and whatnot. And so we built our application in two pieces. We had the API on one side, and we had the client-side app that customers actually interfaced with. Now, this actually created a whole new host of problems for us, right?
Because now we had two sets of controllers and two sets of models and two sets of validations and two routers. And you don't realize how much you really enjoy Form 4 until you don't have it anymore. And it's terrible. So really, our app started to feel like this, right? We just had two cakes stacked on top of each other,
and this was a terrible situation. Any change in the front-end app resulted in a change in the back-end app, and it was just no good. We said let's change this app, but I asked the product manager for that team. I said, okay, do you have any particularly juicy cards where state was just unbearable in our Batman app
and was kind of solved when we moved it back to just Rails. He said, are you kidding? Like, all of them. He then proceeded to send me like eight cards and eventually gave up and said, okay, just search for cards that have hard refresh in them. And so what this means is we had,
so we had parts of our app that were so unreliable that the best solution for our JavaScript application was just to say like, oh, if a user ever comes to this route, it's probably not gonna work. Let's just refresh it. That's ridiculous. So as you can imagine, or as you might know, Shopify kind of abandoned Batman JS in 2014.
We're kind of like left holding this hand, like what do we do? And they've actually been pretty vocal against client-side MVC since then. So this is Toby, the CEO there, just talking about how ridiculous client-side is. I think he tweeted at some point about how the Batman project could cost them
like $100,000 or something like that. Just up in smoke. And as David mentioned yesterday, or on Tuesday, Shopify has been really instrumental in kind of building out Turbolinks 3. So again, we kind of followed Shopify's lead. And as we built the rest of our apps
or rebuilt some of our Batman apps, we rebuilt them squarely on the Rails path. And Rails paths, Sprinkles, SJR, Turbolinks. And actually, to be honest, we kind of like it. I know that that's controversial in here, but we're pretty into it. But we're still writing a lot of JavaScript.
There were a lot of places, this is from a pull request that was opened. It's just a GIF kind of showing something where we have a lot of transient state. This isn't an event that's going to get sent to the server and then respond with some server-rendered JavaScript.
This is purely for the user. This is just a user interaction. It doesn't need to be handled by a Rails controller. We also have pages that are fully real-time. So as I was saying, we have services. We have a service that helps you plan services. And then this is kind of like a rundown for that.
And this happens in real-time. We use Pusher to connect a ton of devices. We have iOS devices, and the person running the presentation can move through, and that's gonna kind of change these items, attracts how much time has gone by. There's like a real-time chat thing. It's like, I mean, it's pretty exciting. It's like a JavaScript MVC's person's dream.
So what we needed was we needed something that would actually scale from these small interactions that we needed it for to these big, full-on pages of our applications where everything was real-time. We found React to be instrumental in that, and instrumental in us being able to stay
on the Rails path, but then just use as little JavaScript as we needed to solve a job, particularly this concept of React components. So we'll talk about that a little bit more. I have two goals for this talk. So my first goal is that you'd be able to walk out of here and ship a React feature in an hour.
Take you like five minutes to set up, and then you have 55 minutes to code. So that's my goal. If any of you accomplish it, tell me, and I'll give you a digital high five. And then my second goal is that you don't make the same mistakes that we did. We made a ton of mistakes.
I mean, as you can see, we made a ton of mistakes in JavaScript, and we made a ton of mistakes just porting our application logic to React. So I don't want you to make the same mistakes that we did. I'm gonna try to show you kind of the ideal path that we're using right now for all of our new development. So let's do a React primer. React is a JavaScript library by Facebook.
It's for creating user interfaces using components. Components do three things. They render, they receive props, and they maintain state. You would do pretty well to think about a React component
as a partial with locals. So let's say we have an audio service, and we want to show the songs that are in this album. So this partial should make sense to anyone who's done Rails for a day. And so that'll render out something like this. It'll render out an unordered list of songs. This particular list is 1989 by Taylor Swift.
Yes, thank you. I may or may not have been able to create this list from my mind, but. So we're just gonna do the easiest steps we can. We're just gonna create a new partial file. We'll just dump the whole thing in there, and then we'll say render songs.
Easy. So now if we really want this to be reusable, we can't say album songs here. We wanna kind of abstract that a little bit, and so we'll just say songs. We'll require some type of local data. And in our view, we update this to say, okay, songs is gonna be album songs. And so now if we want to show a list
of Taylor Swift albums, each of these albums has to have at least 50 plays on my iTunes. This is the best. So we're just gonna iterate over the albums. We're gonna spit out the title, and we're gonna use our partial again. Now these are different, but because we're sending songs in as locals,
it doesn't matter. The partial doesn't care. So you know this, so let's do it in JavaScript now. So instead of render partial, we have a little helper called react component. And instead of using songs, which is going to look for the songs partial, we would use the songs, which is going to look for the songs component
in the window object. Yeah, which one? Oh, sorry, yeah, yeah. So I'm gonna, sorry, this is the same partial code. I'm just blocking parts of it out, so. All right, so now we're gonna grab songs off of the, wow, these look terrible now.
Thank you, thank you for that. So we're gonna use the songs component off the window object. Instead of sending locals in, we just send a hash in. But it's the same thing. We just say songs, album songs. And in React, we call these props, short for properties. So props are immutable, kind of.
If you were at Yehuda's Rust talk yesterday, he talked about how Rust has this concept of ownership and borrowing, and how ownership is the right to destroy or modify something. And when you pass something down as props, like, that component should not modify it, destroy it. Like, they just have the ability to view and use it.
So let's define our component. Can everyone see this now? Everything's looking good? Okay, cool. We have a songs variable. Say react create class. It's a class with a render function. Okay, we're gonna render out an unordered list. We're gonna grab the songs off of props.
And we're gonna iterate over it with map. So it's a little bit different than the Ruby code above it. And because we don't have blocks, we're gonna actually call function for each of these items. We're just gonna take the song and spit it out as a list item, song.name. All right, let's go over that one more time again, just real quick.
So we have songs, it's a React class, has render function, ul, grabs the songs off of props, maps over them, calls this function for each song, and returns a list item with a song name. Okay, so let's practice. So I had this idea of, let's take a Rails app that everyone here knows about.
We'll take the 15-minute blog, and we'll add some real-time comments to it. Whoa! Okay, so if you haven't seen the 15-minute blog, this is the inverted version of the 15-minute blog. So there's a block in there like this
where we have posts, and we're gonna iterate over each comment and spit out the comment body with an HR because it's 2003. So let's go straight to React. So we'll create a comment. It's a React class with a render function, and that render function is going
to return a div with an HR in it. And we're going to take our comment right off props and interpolate that out. Okay, pretty simple. So here in our view, we're gonna use our React component helper. We're gonna spit out the comment component. Man, it's hard to say. I should've chose a different example. Comment component and use the comment.body there, right?
So our app goes from looking like this to looking like this. The astute viewer will say those look exactly the same, and they would be correct, except now these two comments are being rendered in JavaScript, so that's pretty cool. So let's do the rest of this.
We're gonna take the whole block now. We saw this with songs. We're gonna create comments. It's a React class. The render function spits out a div, takes all the comments, maps over them, runs this function for each. We're gonna pull out the body of the comment, and in React, we have this cool syntax where we can use our comment like an HTML tag, right?
So we didn't have to do anything. We just run that, and we can send in a comment like we were with props as an HTML attribute, so that's cool, so we're just gonna send in the body. Cool, take that out, change this to comments, send all the comments down, and now our app goes from looking like this
to looking like this. The astute observers again say that looks exactly the same, and you are correct, except now the entire comment block is rendered in JavaScript. This is pretty cool. So let's get to the real time bit, right? So we have a comments component that renders out comments.
We have a comment component that renders out a single comment, and we're gonna create a comments container, and what this is, you can think about this kind of like a Rails controller, right? So this comments container, it knows how to fetch comments, and it knows which component to render when it has the comments it wants. So again, think about this kind of like a Rails controller.
This isn't special, it's just kind of a convention, this container convention. So here, we're gonna kind of ditch all the stuff that we had before where we're rendering out the comments directly, and we're going to now give, so we're gonna use the comments container, and we're gonna give it a path now, and say hey, this is where you're gonna fetch comments.
This is where you're gonna fetch the JSON for comments. This is what that comments container looks like. This first half is the fetching of comments. We have our render function at the bottom, and we have this get initial state. So these are the APIs that we're gonna talk about. This is, these are just the things
that we haven't talked about yet. These are for kind of managing state and whatnot. These are the place where we actually interact with and set that state, so let's dive into it. So we have a comments container. It returns a comments component,
and we're gonna start by just giving out comments of like an empty array, right? So this isn't, so this is gonna render out nothing. Hey, this is our first interaction with state, and so we have a special object for that in React. There's props and state. It's the only two ways that you interact with data. This is the second of those. This is state. So where props is immutable, state is designed to change.
This container, this comments container knows what state comments is in, and it knows how to get new comments and how to set those comments. So now we can use this API called get initial state, and this is just a way to kind of protect ourselves when we're doing an asynchronous call
to the first time we render, render with an empty state at least, not send undefineds all over the place. So again, we're getting our state from comment state. All right, so this is our function. This is pretty simple. We're actually gonna take the comments path prop that we sent in, and we're gonna fetch that JSON.
Oh, sorry, that we passed in from that view. On success, we're gonna take that data, and we're gonna use a special function called set state. I'm gonna say, hey, the state is now the new data that we got back. You can think about this set state as like a refresh button for your component.
Anytime you call this method with new state, it's going to totally re-render anything that's downline of that tree. So in that case, it's going to render our components, or our comments component, and subsequently every component after that. We have another hook here that we can use.
It's called componentWillMount, and that's just an initializer function. So when this component's ready to go, it's initialized, we can run this function, and here we're just gonna say, hey, get all the comments. And we wanna do that every second. So we're just gonna use polling for now. I'll show you some more interesting examples later.
So now for the first time, we actually see a change. Hopefully you can see it, but as I add comments to the left screen, they're gonna get loaded in the right screen. This isn't particularly exciting, but we didn't write a whole lot of code to get here, and the code that we wrote is all in one place. Like it's totally isolated
to those three component files. We didn't have to change a JavaScript file and then update our view to have a DOM node and all that kind of stuff. It's all there. This is totally isolated. We can implement it totally differently in the future if we need it. It's very cool. So another cool thing about React that I wanna show you is it's very smart about the way that it does updates.
Might be kinda hard to see, but if you look at that list of comments, you'll see that it's only doing an insert of the last comment that I added. So the way this works is that React does re-render on every set state. So right here, we're setting a state with new comments.
It does re-render, but it renders in memory, and it just does a diff to say like, hey, how am I different than the DOM? And then it renders, or it says, okay, we need to change these few things, and then we'll be up to date. But it doesn't grab the whole thing out and then just do an insert of the whole comment block. This is also pretty cool
for a lot of performance reasons. So I showed you about like four things right there to actually manipulate state. So what are a lot of, what are the number of things that you need to know to be effective with React right off the bat? Well, it's not too many. I'll show you a couple of things that I've shown you already, and those that we haven't. So first, this is how you render out a component
in your Rails views. This is how you send in props. Super easy. So this is a greeting component. We're gonna say, hi, Bob, or something like that. This is how you define a component. We're just returning an h2 that says, hi, and we're interpolating the name out.
There's a thing called prop types, which is pretty cool, where you can actually specify what type name should be, which is really handy when you want to, for the reusability of these components. It's really awesome because now in development, if someone tries to use this greeting component and they're not quite sure how it works,
if they try to send in a number, they're gonna get a really cool warning like this in the console, and it's just gonna say, hey, you're trying to use greeting, but you're sending in a number as name, and we really need a string. There's a method called getDefaultProps, and this is kind of like set initial state,
or get initial state, where you can set initial value. So if someone uses this component and they don't pass in a name, we're just gonna say guess, so we'll say, hi, guessed. And kind of think of this as like a or equals in Ruby. Set state, this is like the refresh button of your React components.
Get initial state, you saw this. We can kind of set an initial state for our component. Component will mount. This is where you would do things like getJson. As soon as the component's ready, we're gonna fire off something and get some new data and handle that data. It also has a sibling called componentWillUnmount,
and this is for things like if you are attaching event listeners. So you would have componentWillMount and componentWillUnmount. As this component goes in and out of view, you'd attach event listener, and then you would kind of remove that event listener and clean up after yourself. This works if you were using server-sent events
with pusher, we're using pusher. Pretty cool. So that's about nine things you need to know. Like that's not a lot of things, right? Not a lot of things? Are you guys alive out there? You gals alive out there? Everybody alive out there? This is nine things. This is an incredibly small amount of things
that you need to know, and we're not telling it how to be smart about updates. It's just doing that by itself. We're not grabbing DOM nodes and changing them out and doing all this stuff. We're just saying, hey, want this to render? Whatever the state is, just render that state. Every time you render, just do it the right way, and then figure out on your own time
how to insert in the most effective way. So I wanna show you a little example. This is from our services live app that I was telling you about in the beginning. So if you watch, you can see the clock in the app. This looks so weird. So you can see the clock, and you can see on the right, the only updates happening is that inner HTML,
which is really cool. I mean, this whole, in memory, this entire app is re-rendering, and it's just sending in the new time. So we're getting second snapshots of this application. Here's the chat application. As I add comments, you can look in the table right there.
It's just going to insert those table rows. So I wanna shift a little bit to implementation. So this is something we struggle with a lot. At one point, every single app that we had that used React was doing it a different way.
So I'm not gonna tell you all five or six ways that we were doing it, but I will tell you the way that we landed on, the way that we feel is the most effective and the most honoring of Rails in the asset pipeline. So we use the React Rails gem. This buys you a couple things. It buys you that helper that I was telling you about,
the React component helper that we've been using in all these examples. It's really smart. It uses UJS to mount and unmount your components, and it's really smart about Turbolinks. So whether you use Turbolinks or don't use Turbolinks, it's gonna do the right thing. It's very simple to set up. You just add this gem, you run this installer,
and installer is really pretty minimal. All it does is really give you a components directory to put all your components in. It also gives you this really cool generator. So you just say React component greeting, and it'll spit out this really cool, you know, all the code you need to render out a greeting.
It allows you, it has a nice little syntax for prop types. So if you know that you need a name and a string, it'll render out this for you with the prop types in the top. So if you haven't used Rails assets, this is an incredibly cool project.
What it does is it works on Bower, and so it will, here, let's see. It works on Bower. So in your gem file, all you have to do is add this source block, and then you add these gems that you can find on the Rails assets site. And so as you can see,
there's just a prefix, Rails assets, alt, Rails assets, React router, or whatever. And what Rails assets does is it works on Bower, and it'll pull down the Bower repository alt, or React router, or moment.js. It'll pull that down, and it will create an honest-to-goodness gem for you and return that to you. So you have an honest-to-goodness gem
created from a Bower JavaScript or CSS repository. And this is super easy. This is the easiest way that we've found to be able to pull cool JavaScript libraries into our Rails apps. So the mistake we made was fighting the asset pipeline. We worked a lot with trying to use browserify or webpack and all this kind of stuff,
and there are benefits there, and I'd be happy to talk with you afterwards about what those are. But we found that, for the most part, the easiest solution was the best solution for us. So this is great. It communicates well, and our teams are really happy with it. Let's talk about languages. So some of you might have been watching
and saying, okay, I don't understand what this magic is happening, the whole HTML and JavaScript. And so some of you might have heard the controversy around JSX. And I don't really think this is a big deal. I like it. I like seeing JavaScript right here in my components.
It's nice that I don't have a separate file that's doing this. At the end of the day, it's no different than the way like ERB works or handlebars works. It's just processing out, it's pre-processing our JSX into function calls like this. But we don't have to look at that. We don't have to write that. We can just write it as if we were writing HTML.
All right. So that's the JavaScript one. React Rails comes out of the box with support for CoffeeScript. So you would just append coffee on the back. So you lose a couple of brackets and parentheses and whatnot. The weird part is that you have
to backtick escape out the JSX, which isn't a huge problem if you really love CoffeeScript that much. We don't, so we just don't use it. It's also weird that you have to use this because this is being backticked escaped. You can't use at inside your component. You can use it everywhere else, I'm sorry, inside the template.
You can use it everywhere else, but not inside the template. So what we've really come to love is ES6. There's a little flag you can set up in the React Rails gem that will convert ES6 into ES5 for you. So this is great. Now this has a little bit of a difference in text,
which is fine. You get used to it. We really love it because it buys us all of the things that we really love about CoffeeScript, but not CoffeeScript, and we can just return this JSX right there. So the first thing that's a little bit different is that you define things as a class. So we define this as a greeting class,
and it extends React components. So before we were creating, we were using create class to define our components. Here we're going to just extend the class React component. Also, prop types get pulled out of the class, and they're used as a constructor property.
Two things, pretty simple. One nice thing is that you can actually, React is extremely smart. I was telling you about the great warnings and errors that you can tie into. So if you try to use an API that's strictly dedicated to the create class way of doing things,
when you try to do this as a class, you're going to get a warning, and it's going to say, hey, get initial state was defined on comment, a plain JavaScript class. This is only supported for classes created using React.create class. Did you mean to define a state property instead?
Look, this is an amazing error, and it's all just switching from JavaScript to ES6, and you're doing amazing. I don't even know how they figure this out for me, and they're telling me exactly what I need to do. They're telling me where I need to solve this problem, and what I'm doing wrong, what I need to do. You can learn a thing or two about copywriting from this error.
This is amazing. Anyway, so we go, and whoops, we changed that to the right thing, which I apparently don't have a slide for. So early on, we made the mistake of not embracing JSX. We did a lot of somersaults to try to get around using JSX,
and just drawing out the functions ourselves, and CoffeeScript, and whatnot, and we found that the best path is just to embrace JSX. You really start to love it after about an hour, and this is where Facebook and the React team is hiding a lot of the implementation details from you.
So the most painful updates that we've ever had are the ones where we were trying to use CoffeeScript instead of JSX, and something wasn't hidden from us because of that. So use JSX. It's awesome. Don't make the mistake we did. Use ES6 is really great, and I'm starting to see more and more documentation in React using ES6.
I think it's the way moving forward. A lot of people who are using React really embrace ES6. So I wanna leave you this morning with just this concept of only as much JavaScript as you need. The idea here is stick to the Rails path as much as you can,
and just do the minimal amount of JavaScript you need, and I feel like React helps you there. So this is our, oh, man. My cakes look all funky now. So this is your Rails app, inverted. This is your Rails app with sprinkles,
and this is your Rails app after two years of sprinkles. This is your Rails app using a client-side MVC, and this is what I imagine Turbolinks 3 to be like, where you're actually using the sprinkles to kind of pin down the Ruby views on top of the cake,
but I don't know, and this is the party that we're having with React JS at Planning Center. Thanks so much.