react-rails: an isomorphic match made in heaven

react-rails: an isomorphic match made in heaven

React (which is obvs so hot right now) is hot; It is also a pretty cool view layer, but you have to adopt the entire JS stack to make use of it. OR WAIT, DO YOU!?!?!?!

Let's look at how we can use the Rails asset pipeline, JSON APIs, pre-rendering, and React to build isomorphic rails apps that rule.

We'll start with a quick intro to React, and then get inside Rails to pre-render and render React on the server.

I (JWo) don't say this often, but this is a _compelling_ technology stack.

3b5cb0411cbd1012acab1b60f7ce3606?s=128

Jesse Wolgamott

October 21, 2015
Tweet

Transcript

  1. REACT-RAILS: AN ISOMORPHIC MATCH MADE IN HEAVEN BY @JWO FOR

    HOUSTONRB
  2. FIRST, WHAT IS REACT?

  3. CREATED BY FACEBOOK DESIGNED TO SOLVE THE STATE PROBLEM WITH

    JQUERY WILL RENDER WHENEVER ITS INTERNAL STATE CHANGES VERY FAST WEB COMPONENT BASED
  4. WHY IS IT FAST? INSTEAD OF STORING IN THE DOM,

    REACT HAS ITS OWN "VIRTUAL DOM" THEN, IT SYNCS CHANGES, REUSING WHAT IT CAN https://cdn.tutsplus.com/net/uploads/2013/11/component- dom-tree.png
  5. THE VERY BASICS EACH REACT COMPONENT MUST HAVE A "RENDER"

    FUNCTION THE RENDER FUNCTION HAS HTML INSIDE OF IT. WHEN HTML+JS ARE IN SAME FILE, WE CALL IT JSX
  6. OHHAI Run this code 1 2 3 4 5 6

    7 hosted with ❤ by 1 hosted with ❤ by v a r O h H a i = R e a c t . c r e a t e C l a s s ( { r e n d e r ( ) { r e t u r n < d i v > < h 1 > O h H a i T h e r e ! < / h 1 > < / d i v > } } ) ; view raw ohhai.jsx GitHub R e a c t . r e n d e r ( < O h H a i > < / O h H a i > , d o c u m e n t . b o d y ) ; view raw very-later.js GitHub
  7. YOU CAN RUN JAVASCRIPT, LIKE MAPPING Run this code 1

    2 3 4 5 6 7 8 9 1 0 1 1 1 2 1 3 1 4 1 5 1 6 1 7 hosted with ❤ by v a r N u m b e r s = R e a c t . c r e a t e C l a s s ( { n u m b e r s ( ) { r e t u r n [ 3 , 4 , 5 ] ; } , r e n d e r ( ) { r e t u r n < d i v > < h 1 > T h e r e a r e { t h i s . n u m b e r s ( ) . l e n g t h } n u m b e r s < / h 1 > { t h i s . n u m b e r s ( ) . m a p ( f u n c t i o n ( i ) { r e t u r n < p > T h e r e i s { i } < / p > } ) } < / d i v > } } ) ; R e a c t . r e n d e r ( < N u m b e r s > < / N u m b e r s > , d o c u m e n t . b o d y ) ; view raw numbers.jsx GitHub
  8. WHAT ABOUT STATE? STATE STORES THE COMPONENTS DATA. INSTEAD OF

    IN `DATA-` ATTRIBUTES A COMPONENT SETS ITS OWN STATE
  9. CODE THAT USES STATE Run this code 1 2 3

    4 5 6 7 8 9 1 0 1 1 1 2 1 3 1 4 1 5 1 6 1 7 1 8 hosted with ❤ by v a r T w e e t B o x = R e a c t . c r e a t e C l a s s ( { g e t I n i t i a l S t a t e ( ) { r e t u r n { r e m a i n i n g : 1 4 0 } } , h a n d l e K e y U p ( ) { v a r t e x t = t h i s . r e f s . t w e e t t w e e t . g e t D O M N o d e ( ) . v a l u e ; t h i s . s e t S t a t e ( { r e m a i n i n g : ( 1 4 0 - t e x t . l e n g t h ) } ) ; } , r e n d e r ( ) { r e t u r n < d i v c l a s s N a m e = " t w e e t b o x " > { t h i s . s t a t e . r e m a i n i n g } L e f t < b r / > < t e x t a r e a o n K e y U p = { t h i s . h a n d l e K e y U p } r e f = " t w e e t t w e e t " > < / t e x t a r e a > < / d i v > } } ) ; R e a c t . r e n d e r ( < T w e e t B o x > < / T w e e t B o x > , d o c u m e n t . b o d y ) ; view raw tweetbox.jsx GitHub
  10. CODE THAT FETCHES DATA Run this code 1 2 3

    4 5 6 7 8 9 1 0 1 1 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 9 2 0 2 1 2 2 2 3 2 4 2 5 2 6 2 7 2 8 hosted with ❤ by v a r T a y l o r = R e a c t . c r e a t e C l a s s ( { g e t I n i t i a l S t a t e ( ) { r e t u r n { u r l s : [ ] } ; } , c o m p o n e n t D i d M o u n t ( ) { v a r c o m p o n e n t = t h i s ; f e t c h ( " h t t p : / / a p i . g i p h y . c o m / v 1 / g i f s / s e a r c h ? q = t a y l o r + s w i f t & a p i _ k e y = d c 6 z a T O x F J m z C " ) . t h e n ( f u n c t i o n ( r e s p o n s e ) { r e s p o n s e . j s o n ( ) . t h e n ( f u n c t i o n ( d a t a ) { c o m p o n e n t . s e t S t a t e ( { u r l s : d a t a . d a t a } ) ; } ) ; } ) ; } , r e n d e r ( ) { r e t u r n < d i v i d = " i m a g e s " > { t h i s . s t a t e . u r l s . m a p ( f u n c t i o n ( i m a g e ) { r e t u r n < i m g s r c = { i m a g e . i m a g e s . f i x e d _ h e i g h t . u r l } > < / i m g > } ) } < / d i v > } } ) ; R e a c t . r e n d e r ( < T a y l o r / > , d o c u m e n t . b o d y ) ; view raw taylor.jsx GitHub
  11. WHAT ARE PROPS? PROPS ARE SENT IN FROM A PARENT

    LIKE URLS. OR LIKE THE PRODUCTS TO LOOP OVER
  12. PROPS COME IN FROM THE OUTSIDE STATE IS SET FROM

    THE INSIDE
  13. OK, SO THAT'S REACT. HOW DOES THAT HELP ME?

  14. JAVASCRIPT BUILD SYSTEMS IF YOU DIDN'T WANT TO USE RAILS,

    YOU NEED A BUILD SYSTEM YOU NEED A ROUTER YOU NEED MANY THINGS
  15. WITH RAILS USE RAILS' ASSET PIPELINE USE RAILS FOR AUTHENTICATION

    THE GREAT PAGE LOAD MIX OF RAILS AND REACT
  16. REAL TIME SYSTEMS

  17. SELF UPDATING SYSTEMS

  18. USE THE BEST, EASIEST, PART OF REACT

  19. REACT-RAILS A GEM. BECAUSE OF COURSE IT IS < %

    = r e a c t _ c o m p o n e n t ' T a y l o r ' % > RENDERS THE `TAYLOR` REACT COMPONENT TO THAT AREA OF THE PAGE
  20. SENDING PROPS < % = r e a c t

    _ c o m p o n e n t ' P r o d u c t G r i d ' , { p r o d u c t s : @ p r o d u c t s } % >
  21. SO, YOU CAN SEND PROPS TO A PRODUCTGRID IT THEN

    MAKES AN API CALL EVERY 3 SECONDS TO UPDATE INVENTORY COUNT. [END] NO NEED TO WEIRD RENDERING
  22. OK, BUT I BET THERE'S MORE.

  23. THERE'S MORE

  24. PRERENDER.IO AN ENTIRE SERVICE TO RENDER ANGULAR/REACT/ETC FOR SEO

  25. < % = r e a c t _ c

    o m p o n e n t ' P r o d u c t G r i d ' , { p r o d u c t s : @ p r o d u c t s } , { p r e r e n d e r : t r u e } % >
  26. WHAT JUST HAPPENED

  27. BONUS AWESOME: ACTION CABLE NEW IN RAILS 5, AVAILABLE NOW

  28. g e m ' a c t i o n

    c a b l e ' , g i t h u b : " r a i l s / a c t i o n c a b l e " START A PUMA CABLE PROCESS HAVE A CHANNEL, AND ALSO A SUBSCRIPTION
  29. 1 2 3 4 5 6 7 8 9 1

    0 1 1 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 9 2 0 2 1 2 2 2 3 2 4 2 5 2 6 2 7 2 8 2 9 3 0 3 1 3 2 hosted with ❤ by / / = r e q u i r e d 3 v a r C h a r t i e = R e a c t . c r e a t e C l a s s ( { g e t I n i t i a l S t a t e ( ) { r e t u r n { d a t u m : [ { " v a l u e s " : [ ] , " k e y " : " A v e r a g e " , " c o l o r " : ' # f f 7 f 0 e ' } ] } } , c o m p o n e n t W i l l U n m o u n t ( ) { A p p . v o t e s S u b c r i p t i o n = { } ; } , c o m p o n e n t W i l l M o u n t ( ) { v a r c o m p o n e n t = t h i s ; A p p . v o t e s S u b c r i p t i o n = A p p . c a b l e . s u b s c r i p t i o n s . c r e a t e ( " V o t e s C h a n n e l " , { r e c e i v e d ( d a t a ) { c o m p o n e n t . s e t S t a t e ( { d a t u m : d a t a } ) ; } } ) ; } , r e n d e r ( ) { r e t u r n < d i v > < N V D 3 C h a r t t y p e = ' l i n e C h a r t ' d a t u m = { t h i s . s t a t e . d a t u m } > < / N V D 3 C h a r t > < / d i v > } } ) ; view raw votie.jsx GitHub
  30. BROADCAST THE VOTES THAT VOTIE LISTENS TO A c t

    i o n C a b l e . s e r v e r . b r o a d c a s t " v o t e s " , V o t e . d a t u m
  31. None
  32. None
  33. OK, SO WHAT'S BAD?

  34. ASSET PIPELINE -- WEBPACK TENDS TO WORK'ISH WEBPACK DEPENDENCIES ARE

    HARD YOU _COULD_ GET RID OF ASSET PIPELINE, BUT I FEEL THAT'S A BIG SPICY MEATBALL
  35. PRERENDER TENDS TO WORK WELL, BUT RENDERING JSON IN CONTROLLER

    IS HARDER THAN YOU THINK. JUST USE ACTIVEMODELSERIALIZES
  36. I'M JWO. THE IRON YARD TEX-MEX CONSULTING HANK'S HEROES