$30 off During Our Annual Pro Sale. View Details »

Data Fetching for React Applications

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.

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() { ... } });