Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Data Fetching for React Applications

Avatar for Relay.js Relay.js
January 28, 2015

Data Fetching for React Applications

Data fetching is still a tricky problem, especially as applications become more complex. We'll describe the approach Facebook uses to make data fetching simple for developers, even as a project grows to include dozens of developers and the application becomes as complex as Facebook's news feed.

Avatar for Relay.js

Relay.js

January 28, 2015
Tweet

Other Decks in Technology

Transcript

  1. { id: 3500401, name: "Jing Chen", is_viewer_friend: true, mutual_friends: {

    count: 195 }, profile_picture: { uri: "http://…", width: 50, height: 50 } }
  2. { id: 3500401, name: "Jing Chen", is_viewer_friend: true, mutual_friends: {

    count: 195 }, profile_picture: { uri: "http://…", width: 50, height: 50 } }
  3. GraphQL { "1572451031": { "id": "1572451031", "name": "Daniel Schafer" }

    } node(1572451031) { id, name, birthdate { month, day } }
  4. GraphQL { "1572451031": { "id": "1572451031", "name": "Daniel Schafer", "birthdate":

    { "month": 1, "day": 17, } } } node(1572451031) { id, name, birthdate { month, day } }
  5. GraphQL { "1572451031": { "id": "1572451031", "name": "Daniel Schafer", "birthdate":

    { "month": 1, "day": 17, } } } node(1572451031) { id, name, birthdate { month, day }, friends.first(1) { cursor, node { name } } }
  6. GraphQL { "1572451031": { "id": "1572451031", "name": "Daniel Schafer", "birthdate":

    { "month": 1, "day": 17, }, "friends": [{ "cursor": "3500401", "node": { "name": "Jing Chen", } }] } } node(1572451031) { id, name, birthdate { month, day }, friends.first(1) { cursor, node { name } } }
  7. GraphQL { "1572451031": { "id": "1572451031", "name": "Daniel Schafer", "birthdate":

    { "month": 1, "day": 17, }, "friends": [{ "cursor": "3500401", "node": { "name": "Jing Chen", } }] } } node(1572451031) { id, name, birthdate { month, day }, friends.after(3500401).first(2) { cursor, node { name } } }
  8. GraphQL { "1572451031": { "id": "1572451031", "name": "Daniel Schafer", "birthdate":

    { "month": 1, "day": 17, }, "friends": [{ "cursor": "4802170", "node": { "name": "Lee Byron", } }, { "cursor": "3700061", "node": { "name": "Nick Schrock", } }] } } node(1572451031) { id, name, birthdate { month, day }, friends.after(3500401).first(2) { cursor, node { name } } }
  9. var FriendInfo = React.createClass({ render: function() { return ( <div>

    <span>{this.props.user.name}</span> <span>{this.props.user.mutual_friends.count} mutual friends</span> </div> ); } }); Response Shape
  10. var FriendInfo = React.createClass({ statics: { queries: { } }

    render: function() { return ( <div> <span>{this.props.user.name}</span> <span>{this.props.user.mutual_friends.count} mutual friends</span> </div> ); } }); Response Shape
  11. var FriendInfo = React.createClass({ statics: { queries: { user: function()

    { return graphql` User { name, mutual_friends { count } } `; } } }, render: function() { return ( <div> <span>{this.props.user.name}</span> <span>{this.props.user.mutual_friends.count} mutual friends</span> </div> ); } }); Response Shape
  12. var FriendInfo = React.createClass({ statics: { queries: { user: function()

    { return graphql` User { name, mutual_friends { count } } `; } } }, render: function() { return ( <div> <span>{this.props.user.name}</span> <span>{this.props.user.mutual_friends.count} mutual friends</span> </div> ); } }); Response Shape
  13. var FriendInfo = React.createClass({ statics: { queries: { user: function()

    { return graphql` User { name, mutual_friends { count } } `; } } }, render: function() { return ( <div> <span>{this.props.user.name}</span> <span>{this.props.user.mutual_friends.count} mutual friends</span> </div> ); } }); Response Shape
  14. var FriendInfo = React.createClass({ statics: { queries: { user: function()

    { return graphql` User { name, mutual_friends { count } } `; } } }, render: function() { return ( <div> <span>{this.props.user.name}</span> <span>{this.props.user.mutual_friends.count} mutual friends</span> </div> ); } }); Response Shape
  15. var FriendInfo = React.createClass({ statics: { queries: { user: function()

    { return graphql` User { name, mutual_friends { count } } `; } } }, render: function() { return ( <div> <span>{this.props.user.name}</span> <span>{this.props.user.mutual_friends.count} mutual friends</span> </div> ); } }); Response Shape
  16. Composition var FriendListItem = React.createClass({ render: function() { return (

    <div> <ProfilePic user={this.props.user} /> <FriendInfo user={this.props.user} /> </div> ); } });
  17. Composition var FriendListItem = React.createClass({ statics: { queries: { user:

    function() { return graphql` User { ?? ?? } `; } } }, render: function() { return ( <div> <ProfilePic user={this.props.user} /> <FriendInfo user={this.props.user} /> </div> ); } });
  18. Composition var FriendListItem = React.createClass({ statics: { queries: { user:

    function() { return graphql` User { ${ProfilePic.getQuery('user')}, ${FriendInfo.getQuery('user')} } `; } } }, render: function() { return ( <div> <ProfilePic user={this.props.user} /> <FriendInfo user={this.props.user} /> </div> ); } });
  19. Lifecycle var FriendListItem = React.createClass({ statics: { queries: { user:

    function() { return graphql` User { ${ProfilePic.getQuery('user')}, ${FriendInfo.getQuery('user')} } `; } } } }); Static View
  20. Lifecycle var FriendListItem = React.createClass({ statics: { queries: { user:

    function() { return graphql` User { ${ProfilePic.getQuery('user')}, ${FriendInfo.getQuery('user')} } `; } } } }); Static View FriendListItem
  21. Lifecycle { "1572451031" : { name: "Daniel Schafer", mutual_friends: {

    count: 195 }, profile_picture: { uri: "http://...", width: 50, height: 50 } } } y Server Data
  22. var FriendInfo = React.createClass({ statics: { queries: { user: function()

    { return graphql` User { name, mutual_friends { count } } `; } } }, render: function() { return ( <div> <span>{this.props.user.name}</span> <span>{this.props.user.mutual_friends.count} mutual friends</span> </div> ); } }); Response Shape
  23. Pagination var FriendList = React.createClass({ render: function() { return (

    <div> { this.props.viewer.friends.map( function(user) { return <FriendListItem user={user} />; } ) } </div> ); } });
  24. Pagination var FriendList = React.createClass({ statics: { queries: { viewer:

    function() { return graphql` Viewer { friends { ${FriendListItem.getQuery(‘user’)}, } } `; } } }, render: function() { ... } });
  25. Pagination var FriendList = React.createClass({ statics: { queries: { viewer:

    function() { return graphql` Viewer { friends.first(10) { ${FriendListItem.getQuery(‘user’)}, } } `; } } }, render: function() { ... } });
  26. Pagination var FriendList = React.createClass({ statics: { queryParams: {count: 10},

    queries: { viewer: function(params) { return graphql` Viewer { friends.first(${params.count}) { ${FriendListItem.getQuery(‘user’)}, } } `; } } }, render: function() { ... } });
  27. Pagination var FriendList = React.createClass({ statics: { queryParams: {count: 10},

    queries: { viewer: function(params) { return graphql` Viewer { friends.first(${params.count}) { ${FriendListItem.getQuery(‘user’)}, } } `; } } }, onScrollLoad: function() { this.setQueryParams({count: this.queryParams.count + 5}); }, render: function() { ... } });