SlideShare ist ein Scribd-Unternehmen logo
1 von 26
Downloaden Sie, um offline zu lesen
Front End Workshops
Isomorphic Web Apps
With ReactJs
Marc Torrent
mtorrent@visual-engin.com
Isomorphic what??
First review ReactJS + Redux recap workshops
Universal web apps - Isomorphic
Web Application
Code (JS)
Server - Routing and Data
gathering (Rest API)
ClientBrowser
HTTP Request,
a new Page
With the data,
inject it to our
application code
render() and obtain
valid HTML
HTTP Response with HTML, Web
Application Code and JSON Data
Web Application
Code (JS)
Request Data, AJAX or
Web sockets → JSON Routing
Isomorphic: the Client and the Server share the
same code for routing, data gathering and
rendering.
HTML Page
Server Side Rendering (SSR) with ReactJS
react-dom/server renderToString(ReactElement)
<MyReactComponent {...props} />
HTML + ReactJS
Virtual DOM ID’sReactDOM.render(App(window.APP_PROPS),
document.getElementById('content')
No re-rendering as there’s no difference in Virtual DOM !!!
Server Side Rendering with Redux
react-dom/server const htmlEl = renderToString(ReactElement)
const store = createStore(reducers);
<Provider store={store}>
<MyReactComponent {...props} />
</ Provider>
No re-rendering as there’s no difference in Virtual DOM !!!
const initialState = store.getState();
const html = `
<HTML> <body>
<script>window.initialState =
JSON.Stringify(initialState);</script>
<div>${htmlEl}</div>
</body></HTML>`;
res.send(html);
Client.jsx
const initialState = window.initialState;
const store = createStore(reducers,
initialState);
<Provider store={store}>
<MyReactComponent {...props} />
</ Provider>
Server Side Rendering with React Router
import { createMemoryHistory, RouterContext, match } from 'react-router';
Finds the route from the current
location and returns the
component to be rendered.
Creates a Location object
from the current url to be
used by the match function.
Renders the component
tree for a given router
state.
import { createMemoryHistory, RouterContext, match } from 'react-router';
const history = createMemoryHistory(req.path);
match({ routes, history }, (err, redirectLocation, renderProps) => {


const InitialComponent = (<RouterContext {...renderProps} />);


const componentHTML = renderToString(InitialComponent);
...
Server Side Rendering: server.js - Main Entry Point
Server Side Rendering: server.js - HTML Template
Client main entry point: client.js
Webpack bundles
Entry point Output
Loaders
main: [
‘client.js’
},
vendor: {
‘react’,
‘react-dom’,
‘react-router’,
‘redux’
}
.../main.js
.../vendor.js
.../[chunk_id].chunk.js
Babel_loader: ES6 → ES5
Style_loader |
css_loader | sass_loader
Plugins
HotModule
ReplacementPlugin()
CommonsChunkPlugin()
DefinePlugin()
ProvidePlugin()
ExtractTextPlugin()
Module
Avoiding FOUC - Webpack ExtractTextPlugin
Webpack code splitting
// polyfill webpack require.ensure
if (typeof require.ensure !== 'function') require.ensure = (d, c) =>
c(require);


require.ensure([‘myModulesDependencies’], (require) => {
const a = require('./ModuleA').default;
const b = require('./ModuleB').default;
});
Output
.../main.js
.../vendor.js
.../1.chunk.js
.../2.chunk.js
React Router - Configuration with Plain Routes
<Route path=”/” component={App}>
<IndexRoute component={Dashboard} />
<Route path=”about” component={About} />
<Route path=”inbox” component={Inbox} >
<Route path=”messages/:id” component={Message} />
</Route>
</Route>
{
path: ‘/’,
component: App,
indexRoute: { component: Dashboard },
childRoutes: [
{ path: ‘about’, component: About },
{
path: ‘inbox’,
component: Inbox,
childRoutes: [
{ path: ‘messages/:id’, component: Message}
]
}
]
}
from ...

 to
React Router - Dynamic Routing & WebPack
{
path: ‘/’,
component: App,
indexRoute: { component: Dashboard },
getChildRoutes(location, cb) {
require.ensure([], require => {
cb(null, [
require(‘./About’).default,
require(‘./Inbox’).default
]);
});
}
}
import About from ‘./components/About’;
{
path: ‘about’,
component: About
}
{
path: ‘inbox’,
component: Inbox,
childRoutes: [
{ path: ‘messages/:id’,
component: Message}
]
}
About.js Inbox.js
Dynamic Routing with new Reducers
At initialization we combine reducers to build the store...
const rootReducer = combineReducers({authReducer, otherReducer});
const store = createStore(rootReduer, initialState,
applyMiddleware(...middleware);


<Provider store={store}>
<Router routes={routes} />
</Proider>


But what happens if we load a route containing a new
reducer that is needed for the components of that new
route???
Combining new Reducers - ReducerRegistry
{
path: ‘faq’,
getComponents:(location, cb) {
require.ensure([‘./components/FAQ’, ‘./reducer’], require => {
const FAQ = require(‘./components/FAQ’).default;
const faqReducer = require(‘./reducer’).default;
store.replaceReducer(combineReducers({...existingRedu
cers, faqReducer}));
cb(null, FAQ);
});
}
}
Now we have the initial reducers combined with the new
ones and applied to the store via store.replaceReducer
Data fetching before rendering
We need data to be accessible to Route Components before rendering those
components.
In SSR it’s not possible to fetch data in componentWillMount or
componentDidMount:
1. componentDidMount is not available on server rendering.
2. componentWillMount is called immediately before rendering and changes
in state won’t trigger a re-rendering → fetching data here doesn’t ensures
that the render method will have all the data that is needed.
ReactRouter → onEnter = Function to be called before
rendering a Route’s Component
REDIAL → Data fetching before rendering
HOC exposing three actions to take BEFORE & AFTER
rendering & only CLIENT SIDE.
React Router + Redux + Redial: Server Side
1. Call trigger function which is an action creator that returns
a Promise
2. State is update through usual Redux cycle
3. Render the vurrent Route with the current state
4. Get the state and make it available to the client
React Router + Redux + Redial: provideHooks
FAQ-Component.js
FAQ-Actions.js
React Router + Redux + Redial: Client Side
1. Listen to navigation events: browserHistory.listen()
2. Match routes to get the component
3. Trigger fetch on the component
4. Render the Component
Bonus Track
SEO friendly universal web apps - React-Helmet
Isomorphic Web Apps is intended to improve SEO

.... we need something to manage our meta tags !!!!
React Helmet is the solution for managing the meta tags of a
Route Component
React-Helmet - Server Side Rendering
const head = Helmet.rewind(); head.title.toString()
Thank you!
Workshop 27: Isomorphic web apps with ReactJS

Weitere Àhnliche Inhalte

Was ist angesagt?

Introducing Rendr: Run your Backbone.js apps on the client and server
Introducing Rendr: Run your Backbone.js apps on the client and serverIntroducing Rendr: Run your Backbone.js apps on the client and server
Introducing Rendr: Run your Backbone.js apps on the client and server
Spike Brehm
 
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and JasmineSingle Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
Paulo Ragonha
 
Creating the interfaces of the future with the APIs of today
Creating the interfaces of the future with the APIs of todayCreating the interfaces of the future with the APIs of today
Creating the interfaces of the future with the APIs of today
gerbille
 
AngularJS for designers and developers
AngularJS for designers and developersAngularJS for designers and developers
AngularJS for designers and developers
Kai Koenig
 
Practical AngularJS
Practical AngularJSPractical AngularJS
Practical AngularJS
Wei Ru
 

Was ist angesagt? (20)

Workshop 25: React Native - Components
Workshop 25: React Native - ComponentsWorkshop 25: React Native - Components
Workshop 25: React Native - Components
 
Introducing Rendr: Run your Backbone.js apps on the client and server
Introducing Rendr: Run your Backbone.js apps on the client and serverIntroducing Rendr: Run your Backbone.js apps on the client and server
Introducing Rendr: Run your Backbone.js apps on the client and server
 
Sane Async Patterns
Sane Async PatternsSane Async Patterns
Sane Async Patterns
 
Angular js routing options
Angular js routing optionsAngular js routing options
Angular js routing options
 
AngularJS Basic Training
AngularJS Basic TrainingAngularJS Basic Training
AngularJS Basic Training
 
Angular js
Angular jsAngular js
Angular js
 
Angular 2.0 Routing and Navigation
Angular 2.0 Routing and NavigationAngular 2.0 Routing and Navigation
Angular 2.0 Routing and Navigation
 
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and JasmineSingle Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
 
Creating the interfaces of the future with the APIs of today
Creating the interfaces of the future with the APIs of todayCreating the interfaces of the future with the APIs of today
Creating the interfaces of the future with the APIs of today
 
AngularJS for designers and developers
AngularJS for designers and developersAngularJS for designers and developers
AngularJS for designers and developers
 
An Introduction To Testing In AngularJS Applications
An Introduction To Testing In AngularJS Applications An Introduction To Testing In AngularJS Applications
An Introduction To Testing In AngularJS Applications
 
The AngularJS way
The AngularJS wayThe AngularJS way
The AngularJS way
 
Angular JS
Angular JSAngular JS
Angular JS
 
AngularJS Internal
AngularJS InternalAngularJS Internal
AngularJS Internal
 
Practical AngularJS
Practical AngularJSPractical AngularJS
Practical AngularJS
 
Dynamic Application Development by NodeJS ,AngularJS with OrientDB
Dynamic Application Development by NodeJS ,AngularJS with OrientDBDynamic Application Development by NodeJS ,AngularJS with OrientDB
Dynamic Application Development by NodeJS ,AngularJS with OrientDB
 
Ember.js - A JavaScript framework for creating ambitious web applications
Ember.js - A JavaScript framework for creating ambitious web applications  Ember.js - A JavaScript framework for creating ambitious web applications
Ember.js - A JavaScript framework for creating ambitious web applications
 
AngularJS Basics with Example
AngularJS Basics with ExampleAngularJS Basics with Example
AngularJS Basics with Example
 
Vue, vue router, vuex
Vue, vue router, vuexVue, vue router, vuex
Vue, vue router, vuex
 
AngularJS Directives
AngularJS DirectivesAngularJS Directives
AngularJS Directives
 

Ähnlich wie Workshop 27: Isomorphic web apps with ReactJS

Rest web service_with_spring_hateoas
Rest web service_with_spring_hateoasRest web service_with_spring_hateoas
Rest web service_with_spring_hateoas
Zeid Hassan
 
ĐĄĐ”ĐșŃ€Đ”Ń‚ĐœŃ‹Đč ĐŽĐŸĐșлаЎ ĐŸ React Router - OdessaJS 2014
ĐĄĐ”ĐșŃ€Đ”Ń‚ĐœŃ‹Đč ĐŽĐŸĐșлаЎ ĐŸ React Router - OdessaJS 2014ĐĄĐ”ĐșŃ€Đ”Ń‚ĐœŃ‹Đč ĐŽĐŸĐșлаЎ ĐŸ React Router - OdessaJS 2014
ĐĄĐ”ĐșŃ€Đ”Ń‚ĐœŃ‹Đč ĐŽĐŸĐșлаЎ ĐŸ React Router - OdessaJS 2014
Andrey Listochkin
 

Ähnlich wie Workshop 27: Isomorphic web apps with ReactJS (20)

React loadable
React loadableReact loadable
React loadable
 
React js
React jsReact js
React js
 
Intro react js
Intro react jsIntro react js
Intro react js
 
React JS .NET
React JS .NETReact JS .NET
React JS .NET
 
Rest web service_with_spring_hateoas
Rest web service_with_spring_hateoasRest web service_with_spring_hateoas
Rest web service_with_spring_hateoas
 
React & Redux in Hulu
React & Redux in HuluReact & Redux in Hulu
React & Redux in Hulu
 
using Mithril.js + postgREST to build and consume API's
using Mithril.js + postgREST to build and consume API'susing Mithril.js + postgREST to build and consume API's
using Mithril.js + postgREST to build and consume API's
 
Meteor Meet-up San Diego December 2014
Meteor Meet-up San Diego December 2014Meteor Meet-up San Diego December 2014
Meteor Meet-up San Diego December 2014
 
Server side rendering with React and Symfony
Server side rendering with React and SymfonyServer side rendering with React and Symfony
Server side rendering with React and Symfony
 
ĐĄĐ”ĐșŃ€Đ”Ń‚ĐœŃ‹Đč ĐŽĐŸĐșлаЎ ĐŸ React Router - OdessaJS 2014
ĐĄĐ”ĐșŃ€Đ”Ń‚ĐœŃ‹Đč ĐŽĐŸĐșлаЎ ĐŸ React Router - OdessaJS 2014ĐĄĐ”ĐșŃ€Đ”Ń‚ĐœŃ‹Đč ĐŽĐŸĐșлаЎ ĐŸ React Router - OdessaJS 2014
ĐĄĐ”ĐșŃ€Đ”Ń‚ĐœŃ‹Đč ĐŽĐŸĐșлаЎ ĐŸ React Router - OdessaJS 2014
 
Reactive application using meteor
Reactive application using meteorReactive application using meteor
Reactive application using meteor
 
Maciej Treder ''Angular Universal - a medicine for the Angular + SEO/CDN issu...
Maciej Treder ''Angular Universal - a medicine for the Angular + SEO/CDN issu...Maciej Treder ''Angular Universal - a medicine for the Angular + SEO/CDN issu...
Maciej Treder ''Angular Universal - a medicine for the Angular + SEO/CDN issu...
 
Async Server Rendering in React+Redux at NYTimes (redux-taxi)
Async Server Rendering in React+Redux at NYTimes (redux-taxi)Async Server Rendering in React+Redux at NYTimes (redux-taxi)
Async Server Rendering in React+Redux at NYTimes (redux-taxi)
 
Universal JS Applications with React
Universal JS Applications with ReactUniversal JS Applications with React
Universal JS Applications with React
 
Advanced React
Advanced ReactAdvanced React
Advanced React
 
Universal JS Web Applications with React - Web Summer Camp 2017, Rovinj (Work...
Universal JS Web Applications with React - Web Summer Camp 2017, Rovinj (Work...Universal JS Web Applications with React - Web Summer Camp 2017, Rovinj (Work...
Universal JS Web Applications with React - Web Summer Camp 2017, Rovinj (Work...
 
React & Redux for noobs
React & Redux for noobsReact & Redux for noobs
React & Redux for noobs
 
OttawaJS - React
OttawaJS - ReactOttawaJS - React
OttawaJS - React
 
L2 Web App Development Guest Lecture At University of Surrey 20/11/09
L2 Web App Development Guest Lecture At University of Surrey 20/11/09L2 Web App Development Guest Lecture At University of Surrey 20/11/09
L2 Web App Development Guest Lecture At University of Surrey 20/11/09
 
React JS: A Secret Preview
React JS: A Secret PreviewReact JS: A Secret Preview
React JS: A Secret Preview
 

Mehr von Visual Engineering

Mehr von Visual Engineering (20)

Workshop iOS 4: Closures, generics & operators
Workshop iOS 4: Closures, generics & operatorsWorkshop iOS 4: Closures, generics & operators
Workshop iOS 4: Closures, generics & operators
 
Workshop iOS 3: Testing, protocolos y extensiones
Workshop iOS 3: Testing, protocolos y extensionesWorkshop iOS 3: Testing, protocolos y extensiones
Workshop iOS 3: Testing, protocolos y extensiones
 
Workshop iOS 2: Swift - Structures
Workshop iOS 2: Swift - StructuresWorkshop iOS 2: Swift - Structures
Workshop iOS 2: Swift - Structures
 
Workhop iOS 1: Fundamentos de Swift
Workhop iOS 1: Fundamentos de SwiftWorkhop iOS 1: Fundamentos de Swift
Workhop iOS 1: Fundamentos de Swift
 
Workshop 26: React Native - The Native Side
Workshop 26: React Native - The Native SideWorkshop 26: React Native - The Native Side
Workshop 26: React Native - The Native Side
 
Workshop 23: ReactJS, React & Redux testing
Workshop 23: ReactJS, React & Redux testingWorkshop 23: ReactJS, React & Redux testing
Workshop 23: ReactJS, React & Redux testing
 
Workshop 22: ReactJS Redux Advanced
Workshop 22: ReactJS Redux AdvancedWorkshop 22: ReactJS Redux Advanced
Workshop 22: ReactJS Redux Advanced
 
Workshop 22: React-Redux Middleware
Workshop 22: React-Redux MiddlewareWorkshop 22: React-Redux Middleware
Workshop 22: React-Redux Middleware
 
Workshop 21: React Router
Workshop 21: React RouterWorkshop 21: React Router
Workshop 21: React Router
 
Workshop 20: ReactJS Part II Flux Pattern & Redux
Workshop 20: ReactJS Part II Flux Pattern & ReduxWorkshop 20: ReactJS Part II Flux Pattern & Redux
Workshop 20: ReactJS Part II Flux Pattern & Redux
 
Workshop 19: ReactJS Introduction
Workshop 19: ReactJS IntroductionWorkshop 19: ReactJS Introduction
Workshop 19: ReactJS Introduction
 
Workshop 18: CSS Animations & cool effects
Workshop 18: CSS Animations & cool effectsWorkshop 18: CSS Animations & cool effects
Workshop 18: CSS Animations & cool effects
 
Workshop 15: Ionic framework
Workshop 15: Ionic frameworkWorkshop 15: Ionic framework
Workshop 15: Ionic framework
 
Workshop 8: Templating: Handlebars, DustJS
Workshop 8: Templating: Handlebars, DustJSWorkshop 8: Templating: Handlebars, DustJS
Workshop 8: Templating: Handlebars, DustJS
 
Workshop 11: Trendy web designs & prototyping
Workshop 11: Trendy web designs & prototypingWorkshop 11: Trendy web designs & prototyping
Workshop 11: Trendy web designs & prototyping
 
Workshop 10: ECMAScript 6
Workshop 10: ECMAScript 6Workshop 10: ECMAScript 6
Workshop 10: ECMAScript 6
 
Workshop 9: BackboneJS y patrones MVC
Workshop 9: BackboneJS y patrones MVCWorkshop 9: BackboneJS y patrones MVC
Workshop 9: BackboneJS y patrones MVC
 
Workshop 7: Single Page Applications
Workshop 7: Single Page ApplicationsWorkshop 7: Single Page Applications
Workshop 7: Single Page Applications
 
Workshop 6: Designer tools
Workshop 6: Designer toolsWorkshop 6: Designer tools
Workshop 6: Designer tools
 
Workshop 5: JavaScript testing
Workshop 5: JavaScript testingWorkshop 5: JavaScript testing
Workshop 5: JavaScript testing
 

KĂŒrzlich hochgeladen

Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
VictoriaMetrics
 
Abortion Pill Prices Tembisa [(+27832195400*)] đŸ„ Women's Abortion Clinic in T...
Abortion Pill Prices Tembisa [(+27832195400*)] đŸ„ Women's Abortion Clinic in T...Abortion Pill Prices Tembisa [(+27832195400*)] đŸ„ Women's Abortion Clinic in T...
Abortion Pill Prices Tembisa [(+27832195400*)] đŸ„ Women's Abortion Clinic in T...
Medical / Health Care (+971588192166) Mifepristone and Misoprostol tablets 200mg
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
Health
 
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
masabamasaba
 
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
masabamasaba
 
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
chiefasafspells
 
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
masabamasaba
 

KĂŒrzlich hochgeladen (20)

What Goes Wrong with Language Definitions and How to Improve the Situation
What Goes Wrong with Language Definitions and How to Improve the SituationWhat Goes Wrong with Language Definitions and How to Improve the Situation
What Goes Wrong with Language Definitions and How to Improve the Situation
 
WSO2CON 2024 - API Management Usage at La Poste and Its Impact on Business an...
WSO2CON 2024 - API Management Usage at La Poste and Its Impact on Business an...WSO2CON 2024 - API Management Usage at La Poste and Its Impact on Business an...
WSO2CON 2024 - API Management Usage at La Poste and Its Impact on Business an...
 
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
 
WSO2CON 2024 - How to Run a Security Program
WSO2CON 2024 - How to Run a Security ProgramWSO2CON 2024 - How to Run a Security Program
WSO2CON 2024 - How to Run a Security Program
 
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
 
Artyushina_Guest lecture_YorkU CS May 2024.pptx
Artyushina_Guest lecture_YorkU CS May 2024.pptxArtyushina_Guest lecture_YorkU CS May 2024.pptx
Artyushina_Guest lecture_YorkU CS May 2024.pptx
 
%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand
 
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
 
Abortion Pill Prices Tembisa [(+27832195400*)] đŸ„ Women's Abortion Clinic in T...
Abortion Pill Prices Tembisa [(+27832195400*)] đŸ„ Women's Abortion Clinic in T...Abortion Pill Prices Tembisa [(+27832195400*)] đŸ„ Women's Abortion Clinic in T...
Abortion Pill Prices Tembisa [(+27832195400*)] đŸ„ Women's Abortion Clinic in T...
 
WSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
WSO2Con2024 - Enabling Transactional System's Exponential Growth With SimplicityWSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
WSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
 
tonesoftg
tonesoftgtonesoftg
tonesoftg
 
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
 
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
 
%in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park %in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park
 
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
 
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park %in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
 
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
 
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
 

Workshop 27: Isomorphic web apps with ReactJS

  • 1. Front End Workshops Isomorphic Web Apps With ReactJs Marc Torrent mtorrent@visual-engin.com
  • 2. Isomorphic what?? First review ReactJS + Redux recap workshops
  • 3. Universal web apps - Isomorphic Web Application Code (JS) Server - Routing and Data gathering (Rest API) ClientBrowser HTTP Request, a new Page With the data, inject it to our application code render() and obtain valid HTML HTTP Response with HTML, Web Application Code and JSON Data Web Application Code (JS) Request Data, AJAX or Web sockets → JSON Routing Isomorphic: the Client and the Server share the same code for routing, data gathering and rendering.
  • 4. HTML Page Server Side Rendering (SSR) with ReactJS react-dom/server renderToString(ReactElement) <MyReactComponent {...props} /> HTML + ReactJS Virtual DOM ID’sReactDOM.render(App(window.APP_PROPS), document.getElementById('content') No re-rendering as there’s no difference in Virtual DOM !!!
  • 5. Server Side Rendering with Redux react-dom/server const htmlEl = renderToString(ReactElement) const store = createStore(reducers); <Provider store={store}> <MyReactComponent {...props} /> </ Provider> No re-rendering as there’s no difference in Virtual DOM !!! const initialState = store.getState(); const html = ` <HTML> <body> <script>window.initialState = JSON.Stringify(initialState);</script> <div>${htmlEl}</div> </body></HTML>`; res.send(html); Client.jsx const initialState = window.initialState; const store = createStore(reducers, initialState); <Provider store={store}> <MyReactComponent {...props} /> </ Provider>
  • 6. Server Side Rendering with React Router import { createMemoryHistory, RouterContext, match } from 'react-router'; Finds the route from the current location and returns the component to be rendered. Creates a Location object from the current url to be used by the match function. Renders the component tree for a given router state. import { createMemoryHistory, RouterContext, match } from 'react-router'; const history = createMemoryHistory(req.path); match({ routes, history }, (err, redirectLocation, renderProps) => { 
 const InitialComponent = (<RouterContext {...renderProps} />); 
 const componentHTML = renderToString(InitialComponent); ...
  • 7. Server Side Rendering: server.js - Main Entry Point
  • 8. Server Side Rendering: server.js - HTML Template
  • 9. Client main entry point: client.js
  • 10. Webpack bundles Entry point Output Loaders main: [ ‘client.js’ }, vendor: { ‘react’, ‘react-dom’, ‘react-router’, ‘redux’ } .../main.js .../vendor.js .../[chunk_id].chunk.js Babel_loader: ES6 → ES5 Style_loader | css_loader | sass_loader Plugins HotModule ReplacementPlugin() CommonsChunkPlugin() DefinePlugin() ProvidePlugin() ExtractTextPlugin() Module
  • 11. Avoiding FOUC - Webpack ExtractTextPlugin
  • 12. Webpack code splitting // polyfill webpack require.ensure if (typeof require.ensure !== 'function') require.ensure = (d, c) => c(require); 
 require.ensure([‘myModulesDependencies’], (require) => { const a = require('./ModuleA').default; const b = require('./ModuleB').default; }); Output .../main.js .../vendor.js .../1.chunk.js .../2.chunk.js
  • 13. React Router - Configuration with Plain Routes <Route path=”/” component={App}> <IndexRoute component={Dashboard} /> <Route path=”about” component={About} /> <Route path=”inbox” component={Inbox} > <Route path=”messages/:id” component={Message} /> </Route> </Route> { path: ‘/’, component: App, indexRoute: { component: Dashboard }, childRoutes: [ { path: ‘about’, component: About }, { path: ‘inbox’, component: Inbox, childRoutes: [ { path: ‘messages/:id’, component: Message} ] } ] } from ... 
 to
  • 14. React Router - Dynamic Routing & WebPack { path: ‘/’, component: App, indexRoute: { component: Dashboard }, getChildRoutes(location, cb) { require.ensure([], require => { cb(null, [ require(‘./About’).default, require(‘./Inbox’).default ]); }); } } import About from ‘./components/About’; { path: ‘about’, component: About } { path: ‘inbox’, component: Inbox, childRoutes: [ { path: ‘messages/:id’, component: Message} ] } About.js Inbox.js
  • 15. Dynamic Routing with new Reducers At initialization we combine reducers to build the store... const rootReducer = combineReducers({authReducer, otherReducer}); const store = createStore(rootReduer, initialState, applyMiddleware(...middleware); 
 <Provider store={store}> <Router routes={routes} /> </Proider> 
 But what happens if we load a route containing a new reducer that is needed for the components of that new route???
  • 16. Combining new Reducers - ReducerRegistry { path: ‘faq’, getComponents:(location, cb) { require.ensure([‘./components/FAQ’, ‘./reducer’], require => { const FAQ = require(‘./components/FAQ’).default; const faqReducer = require(‘./reducer’).default; store.replaceReducer(combineReducers({...existingRedu cers, faqReducer})); cb(null, FAQ); }); } } Now we have the initial reducers combined with the new ones and applied to the store via store.replaceReducer
  • 17. Data fetching before rendering We need data to be accessible to Route Components before rendering those components. In SSR it’s not possible to fetch data in componentWillMount or componentDidMount: 1. componentDidMount is not available on server rendering. 2. componentWillMount is called immediately before rendering and changes in state won’t trigger a re-rendering → fetching data here doesn’t ensures that the render method will have all the data that is needed. ReactRouter → onEnter = Function to be called before rendering a Route’s Component
  • 18. REDIAL → Data fetching before rendering HOC exposing three actions to take BEFORE & AFTER rendering & only CLIENT SIDE.
  • 19. React Router + Redux + Redial: Server Side 1. Call trigger function which is an action creator that returns a Promise 2. State is update through usual Redux cycle 3. Render the vurrent Route with the current state 4. Get the state and make it available to the client
  • 20. React Router + Redux + Redial: provideHooks FAQ-Component.js FAQ-Actions.js
  • 21. React Router + Redux + Redial: Client Side 1. Listen to navigation events: browserHistory.listen() 2. Match routes to get the component 3. Trigger fetch on the component 4. Render the Component
  • 23. SEO friendly universal web apps - React-Helmet Isomorphic Web Apps is intended to improve SEO
 .... we need something to manage our meta tags !!!! React Helmet is the solution for managing the meta tags of a Route Component
  • 24. React-Helmet - Server Side Rendering const head = Helmet.rewind(); head.title.toString()