SlideShare a Scribd company logo
🌵
React on Rails
@jocranford
🌵
🌵
The Product and Market
The Front End Development Scene
The Evolution
The Need for Change
THE BEGINNING …
🌵
🌵
🌵
Designed to change the way that you write JavaScript
“Write less, do more.”
Included by default in Rails 3.1
Why jQuery?
🌵
Library of layout and grid components
Easy to add via CDN or files
Create a reasonably nice UI
Smooth interactions
Avoid spending hours playing with JS and CSS
Why Bootstrap?
🌵
YEARS PASS …
🌵
MEANWHILE, THE WORLD MOVED ON …
Browsers were standardising
Mobile internet usage created new demands
JavaScript was becoming a First Class Language
Test frameworks became mainstream
🌵
🌵
The Emergence of React
The Decision
Evolution of the Asset Pipeline
Building the First Components
THE CHANGE!
🌵
One way data flow
Components represent the UI in a specific state
JSX supported HTML and custom component tags
Why is React Different?
🌵
render() {
return (
<aside
className={this.getContainerStyle()}
data-automation-id="Application_Navigation"
>
<div className={styles.top}>
{this.renderCultureAmpLogo()}
{this.renderEnvLabel()}
<img src={Loader} className="loader" />
</div>
<div className={styles.middle}>
{this.renderNavigationLinks()}
</div>
<div className={styles.bottom}>
{this.renderMasquradeUser()}
{this.renderSuperUserAccount()}
{this.renderUserAccount()}
</div>
</aside>
);
}
🌵
Why is React Different?
One way data flow
Components represent the UI in a specific state
JSX supported HTML and custom component tags
Re-renders when state changes
Virtual DOM
Backed by Facebook
Easy to integrate without migrating everything
🌵
Most of our users access our app using desktop
browsers
We can restrict support to modern browsers
We hired a React export to help us through the
transition
SEO was not a concern
Why React Suited Us
One size DOESN’T fit all teams!
🌵
Step 1: Embracing ES6
Block Scoping
Immutable Constants
Arrow Functions
String Interpolation
Spread Operator
Classes
For more: Luke Hoban’s es6features repo
🌵
🌵
Sprockets
Default Rails Asset Pipeline
Browser-ready
assets
Rails assets
🌵
Sprockets
webpack-bundled assets
webpack
React components
Rails assets
Browser-ready
assets
Adding Webpack - Step 1
🌵
Sprockets
webpack-bundled assets
webpack
React components
Rails assets
Browser-ready
assets
Adding Webpack - Step 1
🌵
Sprockets
Browser-ready
assets
Adding Webpack - Step 2
webpack
React components
webpack-bundled assets
Rails assets
🌵
Outputting a React Component in Haml
def react_component(name, props = nil)
content_tag(
:div,
nil,
data: {
react_component: name,
react_props: props
}
)
end
🌵
Registering and Rendering React Components
function registerComponentType(typeName, ComponentType) {
if (registeredComponentTypes.has(typeName)) {
throw new Error(`component class "${typeName}" already registered`);
}
registeredComponentTypes.set(typeName, ComponentType);
if (ready) mountComponents(typeName);
}
...
registerComponentType('NavigationBarApp', NavigationBarApp);
🌵
function mountComponents() {
$('[data-react-component]').toArray().map(node => {
const typeName = $(node).data('react-component');
mountComponent(getRegisteredComponentType(typeName), node);
});
}
function mountComponent(ComponentType, node) {
const props = Immutable.fromJS($(node).data('react-props')).toObject();
const element = <ComponentType {...props} />;
ReactDOM.render(element, node);
}
$(() => {
ready = true;
mountComponents();
});
🌵
function mountComponents() {
$('[data-react-component]').toArray().map(node => {
const typeName = $(node).data('react-component');
mountComponent(getRegisteredComponentType(typeName), node);
});
}
function mountComponent(ComponentType, node) {
const props = Immutable.fromJS($(node).data('react-props')).toObject();
const element = <ComponentType {...props} />;
ReactDOM.render(element, node);
}
$(() => {
ready = true;
mountComponents();
});
🌵
Adding Jest Tests
CSS Modules
Losing Sprockets
Introducing React Router and Redux
Animations
Immutable State
THE EVOLUTION
🌵
Created to work with React
Originally mocked everything by default
Difficult learning curve and bad developer
experience
Ultimately leads to cleaner code
Jest now allows you to choose and by default
does not mock by default
Introducing Jest
(and Mocking by Default)
🌵
Testing Component Output with Shallow Rendering
import TestUtils from 'react-addons-test-utils';
export default function shallowRender(element) {
const shallowRenderer = TestUtils.createRenderer();
shallowRenderer.render(element);
return shallowRenderer.getRenderOutput();
}
🌵
Testing Component Output with Shallow Rendering
it('should render the icon component', () => {
const icon = shallowRender(
<ShortcutLink
label="label"
icon="life-saver"
popupMenuItems={items}
/>
);
const link = ShallowTestUtils.findWithType(icon, 'a');
...
});
🌵
Testing Component Output with Snapshot Tests
it('renders correctly when it is active', () => {
const navigationLink = shallowRender(
<NavigationLink
linkText="text"
path="path"
isActive={true}
iconType="icon"
onClick={onClick}
/>
);
expect(navigationLink).toMatchSnapshot();
});
🌵
Introducing CSS Modules
🌵
.linkItem {
color: red;
font-size: 3em;
text-align: center;
&:hover {
color: #fff;
}
}
...
import styles from './NavigationBarApp.scss';
...
renderCultureAmpLogo() {
return (
<a href="/">
<i className={styles.linkItem} />
</a>
);
}
SCSS File JavaScript File
🌵
webpack
Browser-ready
assets
Rails assets
React components
Getting rid of Sprockets
🌵
Adding Single Page Transitions
🌵
State
Store
Component
Reducer
Action
with Payload
Updated
State
🌵
JavaScript Routing Library
New version matches components to URL
sections
Old version maintained indefinitely
React Router
🌵
User clicks
Action: URL
Changed
Action: Check if
data required
Action: Ajax
Request
Promise
Resolved
Action: Data
Updated
Reducer
processes data
Components
rerender
🌵
npm Package
Supports Springs
Realistic animation curves
Interruptible animations
Issues: rendering PDFs and tests
React Motion
🌵
Immutable JS
Immutable Objects
Most useful: Map, List
Methods return a new
collection
Protects against subtle bugs
Highly optimised
const { Map } = require('immutable')
const map1 = Map({ a: 1, b: 2, c: 3 })
const map2 = map1.set('b', 50)
map1.get('b') // 2
map2.get('b') // 50
🌵
export const Score = StrongRecord(
{
favorable: null,
unfavorable: null,
neutral: null,
significant: null,
},
'Score'
);
...
SignificantScore.propTypes = {
score: React.PropTypes.instanceOf(Score).isRequired,
children: React.PropTypes.node,
hero: React.PropTypes.bool,
};
Using Defined Record Types
🌵
New and better patterns for structuring code
Functional programming principles
How to write cleaner code that is easier to test
What have we learned?
🌵
Legacy JavaScript is still a thing
Massive library of components
Little thought for reusability so far
Lack of overall consistency in CSS
HAPPY EVER AFTER?
🌵
EPILOGUE
Moving towards a shared component library
Experimenting with alternatives like Elm
Starting a team to own the front end experience
🌵
Thank You!
@jocranford

More Related Content

PDF
Railsconf 2017 - React & React Native a common codebase across native and web
PDF
React.js+Redux Workshops
PDF
State Models for React with Redux
PDF
Redux js
PDF
Redux Universal
PDF
Using redux
PDF
Let's discover React and Redux with TypeScript
PPTX
React vs Angular: ups & downs (speaker Oleksandr Kovalov, Binary Studio)
Railsconf 2017 - React & React Native a common codebase across native and web
React.js+Redux Workshops
State Models for React with Redux
Redux js
Redux Universal
Using redux
Let's discover React and Redux with TypeScript
React vs Angular: ups & downs (speaker Oleksandr Kovalov, Binary Studio)

What's hot (20)

PDF
An Overview of the React Ecosystem
PDF
React vs-angular-mobile
PDF
Building React Applications with Redux
PDF
Angular redux
PDF
Intro to ReactJS
PPTX
React & redux
PDF
The Road To Redux
PDF
React + Redux for Web Developers
PDF
Introduce Flux & react in practices (KKBOX)
PPTX
PPTX
React.js - The Dawn of Virtual DOM
PDF
Redux data flow with angular 2
PDF
Creating a WYSIWYG Editor with React
PDF
React & Redux
PDF
Rest web service_with_spring_hateoas
PPTX
React + Redux Introduction
PPTX
Introduction to react and redux
PDF
React && React Native workshop
PPTX
7 Redux challenges
PPTX
Up and Running with ReactJS
An Overview of the React Ecosystem
React vs-angular-mobile
Building React Applications with Redux
Angular redux
Intro to ReactJS
React & redux
The Road To Redux
React + Redux for Web Developers
Introduce Flux & react in practices (KKBOX)
React.js - The Dawn of Virtual DOM
Redux data flow with angular 2
Creating a WYSIWYG Editor with React
React & Redux
Rest web service_with_spring_hateoas
React + Redux Introduction
Introduction to react and redux
React && React Native workshop
7 Redux challenges
Up and Running with ReactJS
Ad

Similar to React on Rails - RailsConf 2017 (Phoenix) (20)

PDF
Integrating React.js Into a PHP Application
PPTX
Let's react - Meetup
PDF
Building Universal Web Apps with React ForwardJS 2017
PPTX
Combining Angular and React Together
PPTX
React & Redux for noobs
PDF
How to React Native
PPTX
PDF
Connect.js - Exploring React.Native
PPTX
Intro react js
PDF
React & The Art of Managing Complexity
PDF
Component level caching with react
PDF
Styling components with JavaScript
PDF
Full Stack Scala
PDF
Advanced SharePoint 2010 and 2013 Web Part Development by Rob Windsor - SPTec...
PPTX
React outbox
KEY
Javascript unit testing, yes we can e big
KEY
Jarv.us Showcase — SenchaCon 2011
PDF
Backbone.js — Introduction to client-side JavaScript MVC
PPTX
React - Start learning today
PDF
Overview of The Scala Based Lift Web Framework
Integrating React.js Into a PHP Application
Let's react - Meetup
Building Universal Web Apps with React ForwardJS 2017
Combining Angular and React Together
React & Redux for noobs
How to React Native
Connect.js - Exploring React.Native
Intro react js
React & The Art of Managing Complexity
Component level caching with react
Styling components with JavaScript
Full Stack Scala
Advanced SharePoint 2010 and 2013 Web Part Development by Rob Windsor - SPTec...
React outbox
Javascript unit testing, yes we can e big
Jarv.us Showcase — SenchaCon 2011
Backbone.js — Introduction to client-side JavaScript MVC
React - Start learning today
Overview of The Scala Based Lift Web Framework
Ad

More from Jo Cranford (6)

PDF
R spec let there be tests
KEY
Test Driven Development - For Girl Geeks Night Sydney
PDF
Testing javascriptwithjasmine sydjs
PDF
Testing javascriptwithjasmine ddd-sydney
PDF
Why (I think) CoffeeScript Is Awesome
PPTX
Less ismorewithcoffeescript webdirectionsfeb2012
R spec let there be tests
Test Driven Development - For Girl Geeks Night Sydney
Testing javascriptwithjasmine sydjs
Testing javascriptwithjasmine ddd-sydney
Why (I think) CoffeeScript Is Awesome
Less ismorewithcoffeescript webdirectionsfeb2012

Recently uploaded (20)

PDF
Encapsulation theory and applications.pdf
PDF
Assigned Numbers - 2025 - Bluetooth® Document
PDF
Profit Center Accounting in SAP S/4HANA, S4F28 Col11
PDF
Unlocking AI with Model Context Protocol (MCP)
PDF
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
PDF
NewMind AI Weekly Chronicles - August'25-Week II
PDF
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
PDF
Agricultural_Statistics_at_a_Glance_2022_0.pdf
PPTX
Digital-Transformation-Roadmap-for-Companies.pptx
PDF
gpt5_lecture_notes_comprehensive_20250812015547.pdf
PDF
Machine learning based COVID-19 study performance prediction
PPTX
A Presentation on Artificial Intelligence
PPT
Teaching material agriculture food technology
PPTX
Machine Learning_overview_presentation.pptx
PDF
Review of recent advances in non-invasive hemoglobin estimation
PDF
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
PDF
Spectral efficient network and resource selection model in 5G networks
PPTX
ACSFv1EN-58255 AWS Academy Cloud Security Foundations.pptx
PPTX
Cloud computing and distributed systems.
PDF
Network Security Unit 5.pdf for BCA BBA.
Encapsulation theory and applications.pdf
Assigned Numbers - 2025 - Bluetooth® Document
Profit Center Accounting in SAP S/4HANA, S4F28 Col11
Unlocking AI with Model Context Protocol (MCP)
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
NewMind AI Weekly Chronicles - August'25-Week II
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
Agricultural_Statistics_at_a_Glance_2022_0.pdf
Digital-Transformation-Roadmap-for-Companies.pptx
gpt5_lecture_notes_comprehensive_20250812015547.pdf
Machine learning based COVID-19 study performance prediction
A Presentation on Artificial Intelligence
Teaching material agriculture food technology
Machine Learning_overview_presentation.pptx
Review of recent advances in non-invasive hemoglobin estimation
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
Spectral efficient network and resource selection model in 5G networks
ACSFv1EN-58255 AWS Academy Cloud Security Foundations.pptx
Cloud computing and distributed systems.
Network Security Unit 5.pdf for BCA BBA.

React on Rails - RailsConf 2017 (Phoenix)