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
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