isomorphic react in real life
TRANSCRIPT
Who am I?
• Frond end developer at State
• Performance, tooling and open source geek
Isomorphic new site: http://alpha.state.com
Penthouse, Critical Path CSS Generator:
https://github.com/pocketjoso/penthouse
This talk
• Background: Isomorphism, React
• State’s isomorphic React render flow
- Data
- Bootstrap
- Stores
Isomorphic JavaScript
• Shared JS running both client and server
• Performance, graceful degradation, Accessibility, SEO
Isomorphic React
• Easy - React.renderToString()
• What about data fetching, re-using render state, stores
React render flow (client)
RenderFetch
data
Routing
tableURL
props = {
page: ExplorePage
};
React.render(
<App {…props} />,
containerElement
);
React render flow (client)
React Lifecycle method componentDidMount: http://facebook.github.io/react/docs/component-specs.html#mounting-componentdidmount
RenderFetch
data
Routing
tableURL
props = {
page: ExplorePage
};
React.render(
<App {…props} />,
containerElement
);
componentDidMount
React render flow (client)
RenderFetch
data
Routing
tableURL
props = {
page: ExplorePage
};
React.render(
<App {…props} />,
containerElement
);
componentDidMount
…
$.get().then(result){
this.setState({data:
result});
});
React render flow (client)
props = {
page: ExplorePage
};
can’t use on the server
RenderFetch
data
Routing
tableURL
React.render(
<App {…props} />,
containerElement
);
componentDidMount
…
$.get().then(result){
this.setState({data:
result});
});
Isomorphic React render flow
Make requests
page asked for
React.
render/
renderToString(
<App {…props} />
);
Pre fetch
dataRender
Routing
tableURL
props = {
page: ExplorePage
};
Isomorphic React render flow
Make requests
page asked for
React.
render/
renderToString(
<App {…props} />
);
Pre fetch
dataRender
Routing
tableURL
props = {
page: ExplorePage
};
Pre data fetching
React Statics component property: http://facebook.github.io/react/docs/component-specs.html#statics
Isomorphic React render flow
data =
ExplorePage.
requestForProps();
Routing
tableURL
Pre fetch
dataRender
React.
render/
renderToString(
<App {…props} />
);
props = {
page: ExplorePage
};
Isomorphic React render flow
data =
ExplorePage.
requestForProps();
props.data = data;
Routing
tableURL
Pre fetch
dataRender
React.
render/
renderToString(
<App {…props} />
);
props = {
page: ExplorePage
};
Bootstrapping render context
React.render(
<App {…props}/>
);
Server Client
React.renderToString(
<App {…props}/>
);
Flux
• Data changing over time (during a session)
• Cached data
Should I use Flux? https://medium.com/@dan_abramov/the-case-for-flux-379b7d1982c6
Flux
• Data changing over time (during a session)
• Cached data
Should I use Flux? https://medium.com/@dan_abramov/the-case-for-flux-379b7d1982c6
Stores listening for request data
Request
response
data
Distribute StoresNormalise
statement : {
creator : {
id : 12312,
name: Jonas
…
},
id: 199,
text: ‘This is …’
}
Stores listening for request data
Normalize data: https://github.com/gaearon/normalizr
Request
response
data
Distribute Stores
statement : {
creator : {
id : 12312,
name: Jonas
…
},
id: 199,
text: ‘This is …’
}
entities: {
users: {
12312: {
name: Jonas
}
},
statements: {
199: {
text: ‘This is …’
creator: 12312
}
}
}
Normalise
Stores listening for request data
Request
response
data
Distribute StoresNormalise
trigger(users)
trigger(statements)
statement : {
creator : {
id : 12312,
name: Jonas
…
},
id: 199,
text: ‘This is …’
}
entities: {
users: {
12312: {
name: Jonas
}
},
statements: {
199: {
text: ‘This is …’
creator: 12312
}
}
}
Stores listening for request data
UserStore = {
listenTo(
userProvider,
function(users){
// merge new users
// to store’s data
}
}
Request
response
data
Distribute Stores
statement : {
creator : {
id : 12312,
name: Jonas
…
},
id: 199,
text: ‘This is …’
}
Normalise
trigger(users)
trigger(statements)
entities: {
users: {
12312: {
name: Jonas
}
},
statements: {
199: {
text: ‘This is …’
creator: 12312
}
}
}
Full Render sequence: Server
• (Start stores when booting server)
• Execute requests via requestForProps for Page
• Distribute data to Stores (if not Automatic)
• React.RenderToString()
• Snapshot Stores, create render context JSON
• Send HTML to client
• Reset Stores
Full Render sequence: Client
• Parse render context JSON
• Start stores, and restore via snapshots
• React.render, with props from render context
Summary
• Fetch data before rendering React
• Statics to co-locate data requests with component logic
• Bootstrap server render context
• Snapshot, restore and reset Stores
• Optional: Auto distribute request data to Stores
Questions?@pocketjoso
Blog post based on this talk
http://jonassebastianohlsson.com/blog/2015/03/24/isomorphic-react-in-real-life/