Missing Pages: ReactJS/Flux/GraphQL/RelayJS. Shed light on assumptions/details glossed over by Facebook docs. Presented at Tokyo React.js Meetup #3 (http://reactjs-meetup.connpass.com/event/26229/)
Japanese version: https://www.slideshare.net/KhorSoonHin/reactjs-3-meetup-ja
Video: https://youtu.be/YFuQlKBXlmA
2. Shed light on assumptions/details
glossed over in FBâs docs
3. Agenda
â Using pure Flux
â GraphQL
â Sans RelayJS
â Setup GraphQL on non-NodeJS servers
â RelayJS
â Revisiting ReactJS: Reduce coupling, increase reusability
â What RelayJS Brings to GraphQL
â Setup RelayJS/GraphQL on non-NodeJS servers
4. React Family: In a Few Words ...
â ReactJS: UI data & rendering
â Flux: Data flow & code organization
â GraphQL: Single API endpoint data retrieval
â RelayJS: React component data declaration & co-location
15. GraphQL: Enabling the Server
Browser
GraphQL
Server
Bundled
JS
GraphQL
over
http(s), etc.
Any Server
Server
Libraries
graphql
GraphQL
Schema
in Hash
17. GraphQL: Required JS Libraries
Browser
GraphQL
Server
Bundled
JS
Bundled
JS
Any Server
JS Libraries
react
react-dom
graphql
GraphQL
over
http(s), etc.
Server
Libraries
graphql
GraphQL
Schema
in Hash
18. GraphQL: Bundling Your JS Code
Browser
GraphQL
Server
Bundled
JS
Bundled
JS
Any Server
JS Libraries
react
react-dom
graphql
GraphQL
over
http(s), etc.
Server
Libraries
graphql
Your
JS
browserify/w
ebpackGraphQL
Schema
in Hash
24. ReactJS (cont.)
Abstraction
Each ReactJS element knows:
â The data it needs
â How to render itself with HTML fragments
â The data it passes to its children
28. Passing Data to Children
this.props = {
store:
name: âHello Shopâ
categories: [
{
name: 'Sporting Goods',
items: [
{ name: 'Football', price: ⊠}
âŠ
],
},
...
],
},
}
Use Data & Render
this.props.store.name
Pass Down
this.props.store.categories
29. Not so Loose Coupling, Not so High Reuse
â Parent needs to know about childâs data
â Need to fetch data for children
â Need to pass correct data to children
render() {
return (
<Store>{this.props.store} />
<Categories categories={this.props.store.categories} />
)
}
37. Passing Data to Children
this.props = {
store:
name: âHello Shopâ
categories: [
{
name: 'Sporting Goods',
items: [
{ name: 'Football', price: ⊠}
âŠ
],
},
...
],
},
}
Use Data & Render
this.props.store.name
Pass Down
this.props.store.categories
38. Not so Loose Coupling, Not so High Reuse
â Parent needs to need NOT know about childâs data
â Need to fetch data for children
â Need to pass correct data to children
render() {
return (
<Store>{this.props.store} />
<Categories categories={this.props.store.categories} />
)
}
58. Action Creator
TodoActions: {
create: function(text) {
// Take some action, e.g., call REST API
AppDispatcher.dispatch({
actionType: TodoConstants.TODO_CREATE, // Basically âcreateâ
text: text
});
},
âŠ.
}
59. Store
AppDispatcher.register(function(action) { // action is passed in by Action Creator
var event = action.event;
switch(action.actionType) {
case TodoConstants.TODO_CREATE:
// Do whatever, e.g., update local store data or fetch fresh data from server
TodoStore.emitChange();
break;
âŠ.
}
}
register
60. Store (cont.)
var TodoStore = assign({}, EventEmitter.prototype, {
// EventEmitter provides emit, on, removeListener, etc. methods
addChangeListener: function(callback) {
this.on(CHANGE_EVENT, callback);
},
removeChangeListener: function(callback) {
this.removeListener(CHANGE_EVENT, callback);
},
emitChange: function() {
this.emit(CHANGE_EVENT);
},
...
}
register
61. Controller-View
// This is where React is used
var TodoApp = React.createClass({
componentDidMount: function() {
TodoStore.addChangeListener(this._onChange);
},
componentWillUnmount: function() {
TodoStore.removeChangeListener(this._onChange);
},
_onChange: function() {
this.setState(TodoStore.getData());
},
...
}
register