Upload
react-conf-brasil
View
147
Download
1
Embed Size (px)
Citation preview
Relay ModernDeclarative Data Fetching
Sibelius Seraphini
Sibelius Seraphini
@sibelius @sseraphini
2
Data Fetching
Which problem does it solve?
3
- Duplicate fetch logic- Caching is hard- Data fetching is hard to optimize- Hard to handle different endpoints- Pagination can be tricky- Underfetching- Overfetching
Data Fetching is tricky
4
5
6
7
8
- Declarative (declare data your component needs)
- Colocating (component + data requirement)
- Performance- Common patterns (e.g., pagination)
Value proposition
9
- Subscriptions- Mutations
- Data consistency- Optimistic updates- Error handling
Value Proposition
10
- Static queries- Ahead of time code generation- Compat mode- Simpler and more predictable API- More light-weight (20% less)- Faster performance- Persisted Queries- Garbage Collection
What's new in Relay Modern
11
- GraphQL Subscriptions & Live Queries
- Injectable Custom Field Handlers- Simpler Mutation API- Client Schema Extensions- Flowtype Generation- Extensible Core- Closer API to GraphQL Spec
- no need for Viewer (Relay Classic)
What's new in Relay Modern
12
Relay Modern
Concepts
13
const UserRow = ({ user }) => (
<View>
<Text>{user.name}</Text>
<Text>{user.email}</Text>
</View>
);
const UserRowFragmentContainer = createFragmentContainer(UserRow, {
user: graphql`
fragment UserRow_user on User {
name
}
`,
});
Data Components (aka containers)
14
<QueryRenderer
environment={environment}
query={graphql`
query UserQuery($id: ID!) {
user(id: $id) {
...UserRow_user
}
}
`}
variables={{id: '110798995619330'}}
render={({error, props}) => {
if (error) {
return <View>{error.message}</View>;
}
if (props) {
return <UserFragmentContainer {...props} />
}
return <View>Loading</View>;
}}
/>
QueryRenderer (root of Relay tree)
15
RefetchContainerexport default createRefetchContainer(FeedStories, {
feed: graphql`
fragment FeedStories_feed on Feed
@argumentDefinitions(
count: {type: "Int", defaultValue: 10}
) {
stories(first: $count) {
edges {
node {
id
...Story_story
}
}
}
}
`
},
graphql`
query FeedStoriesRefetchQuery($count: Int) {
feed {
...FeedStories_feed @arguments(count: $count)
}
}
`,
); 16
RefetchContainer - refetch
_loadMore() {
// Increments the number of stories being rendered by 10.
const refetchVariables = fragmentVariables => ({
count: fragmentVariables.count + 10,
});
this.props.relay.refetch(refetchVariables, null);
}
17
Mutations
- A Write then Read
const mutation = graphql`
mutation AddShipMutation($input: AddShipData!) {
addShip(input: $input) {
faction {
ships {
id
}
}
newShipEdge
}
}
`;
18
Mutations - Update Store
const configs = [{
type: 'RANGE_ADD',
parentID: 'shipId',
connectionInfo: [{
key: 'AddShip_ships',
rangeBehavior: 'append',
}],
edgeName: 'newShipEdge',
}];
- RANGE_ADD - add node to edge- RANGE_DELETE - remove node from edge- NODE_DELETE - remove node from store- updater - imperative API
19
Subscriptions
const subscription = graphql`
subscription MarkReadNotificationSubscription(
$storyID: ID!
) {
markReadNotification(storyID: $storyID) {
notification {
seenState
}
}
}
`;
20
Debugging
21
Resources
22
- https://github.com/sibelius/ReactNavigationRelayModern
- https://reactjs.org/blog/2015/02/20/introducing-relay-and-graphql.html
- https://facebook.github.io/relay/- https://code-cartoons.com/a-cartoon-intro-to-fa
cebook-s-relay-part-1-3ec1a127bca5
I didn't mention
23
- GraphQL/Relay compiler- Babel plugin Relay- Live Queries- PaginationContainer- Mutation Updater Imperative API- Relay Directives- Relay Network Layer- Relay Environment- Cache
Is Relay Modern the Future?
Sibelius