You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardexpand all lines: meta/meeting-notes/2016-12-09-update.md
+1-1
Original file line number
Diff line number
Diff line change
@@ -2,7 +2,7 @@
2
2
3
3
It's been a while since our last meeting notes, thanks for your patience!
4
4
5
-
Over the last couple of months we've been focusing on building an experimental new core (that we've referred to as Relay "2") and integrating it into products internally. During this process we've refined the new apis, fixed bugs, added missing features, and worked to confirm our hypothesis that the more static core could bring performance improvements on mobile devices. The results so far are promising and we're continuing to pursue this direction.
5
+
Over the last couple of months we've been focusing on building an experimental new core (that we've referred to as Relay "2") and integrating it into products internally. During this process we've refined the new APIs, fixed bugs, added missing features, and worked to confirm our hypothesis that the more static core could bring performance improvements on mobile devices. The results so far are promising and we're continuing to pursue this direction.
6
6
7
7
We've also established a migration pathway for products currently using Relay. Over the next few months we'll be deprecating the current APIs (e.g. `RelayContainer`) and introducing a new product API: slimmed down evolutions of the `RelayRenderer`/`RelayRootContainer`, `RelayContainer`, `RelayMutation`, etc. Products can incrementally migrate to the new APIs, which are simpler and more predictable on their own. When fully converted, products can then toggle a switch to enable the experimental core, unlocking performance optimizations and new features such as persisted queries.
> NOTE: Relay automatically manages the query data retention based on any mounted query components that are rendering the data, so you usually should not need to call retain directly within product code. For any advanced or special use cases, query data retention should usually be handled within infra-level code, such as a Router.
46
+
:::note
47
+
Relay automatically manages the query data retention based on any mounted query components that are rendering the data, so you usually should not need to call retain directly within product code. For any advanced or special use cases, query data retention should usually be handled within infra-level code, such as a Router.
Copy file name to clipboardexpand all lines: website/docs/guided-tour/refetching/refetching-fragments-with-different-data.md
+2-2
Original file line number
Diff line number
Diff line change
@@ -75,12 +75,12 @@ Let's distill what's happening in this example:
75
75
76
76
* `useRefetchableFragment` behaves similarly to [`useFragment`](../../../api-reference/use-fragment/) (see the [Fragments](../../rendering/fragments/) section), but with a few additions:
77
77
* It expects a fragment that is annotated with the `@refetchable` directive. Note that `@refetchable` directive can only be added to fragments that are "refetchable", that is, on fragments that are on `Viewer`, on `Query`, on any type that implements `Node` (i.e. a type that has an `id` field), or on a [`@fetchable`](https://fb.workplace.com/groups/graphql.fyi/permalink/1539541276187011/) type.
78
-
* It returns a `refetch` function, which is already Flowtyped to expect the query variables that the generated query expects.
78
+
* It returns a `refetch` function, which is already Flow-typed to expect the query variables that the generated query expects.
79
79
* It takes two Flow type parameters: the type of the generated query (in our case `CommentBodyRefetchQuery`), and a second type which can always be inferred, so you only need to pass underscore (`_`).
80
80
* We're calling the `refetch` function with 2 main inputs:
81
81
* The first argument is the set of variables to fetch the fragment with. In this case, calling `refetch` and passing a new set of variables will fetch the fragment again *with the newly provided variables*. The variables you need to provide are a subset of the variables that the `@refetchable` query expects; the query will require an `id`, if the type of the fragment has an `id` field, and any other variables that are transitively referenced in your fragment.
82
82
* In this case we're passing the current comment `id` and a new value for the `translationType` variable to fetch the translated comment body.
83
-
* We are not passing a second options argument in this case, which means that we will use the default `fetchPolicy` of `‘store-or-network'`, which will skip the network request if the new data for that fragment is already cached (as we covered in [Reusing Cached Data For Render](../../reusing-cached-data/)).
83
+
* We are not passing a second options argument in this case, which means that we will use the default `fetchPolicy` of `'store-or-network'`, which will skip the network request if the new data for that fragment is already cached (as we covered in [Reusing Cached Data For Render](../../reusing-cached-data/)).
84
84
* Calling `refetch` will re-render the component and may cause `useRefetchableFragment` to suspend (as explained in [Loading States with Suspense](../../rendering/loading-states/)). This means that you'll need to make sure that there's a `Suspense` boundary wrapping this component from above in order to show a fallback loading state.
Copy file name to clipboardexpand all lines: website/docs/guided-tour/refetching/refreshing-fragments.md
+1-1
Original file line number
Diff line number
Diff line change
@@ -94,7 +94,7 @@ Let's distill what's happening in this example:
94
94
95
95
* `useRefetchableFragment` behaves similarly to [`useFragment`](../../../api-reference/use-fragment/) (see the [Fragments](../../rendering/fragments/) section), but with a few additions:
96
96
* It expects a fragment that is annotated with the `@refetchable` directive. Note that `@refetchable` directive can only be added to fragments that are "refetchable", that is, on fragments that are on `Viewer`, on `Query`, on any type that implements `Node` (i.e. a type that has an `id` field).
97
-
* It returns a `refetch` function, which is already Flowtyped to expect the query variables that the generated query expects
97
+
* It returns a `refetch` function, which is already Flow-typed to expect the query variables that the generated query expects
98
98
* It takes two Flow type parameters: the type of the generated query (in our case `UserComponentRefreshQuery`), and a second type which can always be inferred, so you only need to pass underscore (`_`).
99
99
* We're calling the `refetch` function with 2 main inputs:
100
100
* The first argument is the set of variables to fetch the fragment with. In this case, calling `refetch` and passing an empty set of variables will fetch the fragment again *with the exact same variables the fragment was originally fetched with,* which is what we want for a refresh.
* `useFragment` takes a fragment definition and a *fragment reference*, and returns the corresponding `data` for that fragment and reference.
90
+
* This is similar to `usePreloadedQuery`, which takes a query definition and a query reference.
90
91
* A *fragment reference* is an object that Relay uses to *read* the data declared in the fragment definition; as you can see, the `UserComponent_user` fragment itself just declares fields on the `User` type, but we need to know *which* specific user to read those fields from; this is what the fragment reference corresponds to. In other words, a fragment reference is like *a pointer to a specific instance of a type* that we want to read data from.
91
92
* Note that *the component is automatically subscribed to updates to the fragment data*: if the data for this particular `User` is updated anywhere in the app (e.g. via fetching new data, or mutating existing data), the component will automatically re-render with the latest updated data.
92
93
* Relay will automatically generate Flow types for any declared fragments when the compiler is run, so you can use these types to declare the type for your Component's `props`.
93
94
* The generated Flow types include a type for the fragment reference, which is the type with the `$key` suffix: `<fragment_name>$key`, and a type for the shape of the data, which is the type with the `$data` suffix: `<fragment_name>$data`; these types are available to import from files that are generated with the following name: `<fragment_name>.graphql.js`.
94
-
* We use our [lint rule](https://github.com/relayjs/eslint-plugin-relay) to enforce that the type of the fragment reference prop is correctly declared when using `useFragment`. By using a properly typed fragment reference as input, the type of the returned `data` will automatically be Flowtyped without requiring an explicit annotation.
95
+
* We use our [lint rule](https://github.com/relayjs/eslint-plugin-relay) to enforce that the type of the fragment reference prop is correctly declared when using `useFragment`. By using a properly typed fragment reference as input, the type of the returned `data` will automatically be Flow-typed without requiring an explicit annotation.
95
96
* In our example, we're typing the `user` prop as the fragment reference we need for `useFragment`, which corresponds to the `UserComponent_user$key` imported from `UserComponent_user.graphql`, which means that the type of `data` above would be: `{ name:?string, profile_picture:?{ uri:?string } }`.
96
97
* Fragment names need to be globally unique. In order to easily achieve this, we name fragments using the following convention based on the module name followed by an identifier: `<module_name>_<property_name>`. This makes it easy to identify which fragments are defined in which modules and avoids name collisions when multiple fragments are defined in the same module.
97
98
@@ -259,7 +260,11 @@ There are a few things to note here:
259
260
260
261
* `UserComponent` both renders `UsernameSection`, *and* includes the fragment declared by `UsernameSection` inside its own `graphql` fragment declaration.
261
262
* `UsernameSection` expects a *fragment reference* as the `user` prop. As we've mentioned before, a fragment reference is an object that Relay uses to *read* the data declared in the fragment definition; as you can see, the child `UsernameSection_user` fragment itself just declares fields on the `User` type, but we need to know *which* specific user to read those fields from; this is what the fragment reference corresponds to. In other words, a fragment reference is like *a pointer to a specific instance of a type* that we want to read data from.
262
-
* Note that in this case the `user` passed to `UsernameSection`, i.e. the fragment reference, *doesn't actually contain any of the data declared by the child `UsernameSection` component*; instead, `UsernameSection` will use the fragment reference to read the data *it* declared internally, using `useFragment`. This prevents the parent from implicitly creating dependencies on data declared by its children, and vice-versa, which allows us to reason locally about our components and modify them without worrying about affecting other components. If this wasn't the case, and the parent had access to the child's data, modifying the data declared by the child could break the parent. This is known as [*data masking*](../../../principles-and-architecture/thinking-in-relay/).
263
+
* Note that in this case the `user` passed to `UsernameSection`, i.e. the fragment reference, *doesn't actually contain any of the data declared by the child `UsernameSection` component*; instead, `UsernameSection` will use the fragment reference to read the data *it* declared internally, using `useFragment`.
264
+
* This means that the parent component will not receive the data selected by a child component (unless that parent explicitly selected the same fields). Likewise, child components will not receive the data selected by their parents (again, unless the child selected those same fields).
265
+
* This prevents separate components from *even accidentally* having implicit dependencies on each other. If this wasn't the case, modifying a component could break other components!
266
+
* This allows us to reason locally about our components and modify them without worrying about affecting other components.
267
+
* This is known as [*data masking*](../../../principles-and-architecture/thinking-in-relay/).
263
268
* The *fragment reference* that the child (i.e. `UsernameSection`) expects is the result of reading a parent fragment that *includes* the child fragment. In our particular example, that means the result of reading a fragment that includes `...UsernameSection_user` will be the fragment reference that `UsernameSection` expects. In other words, the data obtained as a result of reading a fragment via `useFragment` also serves as the fragment reference for any child fragments included in that fragment.
0 commit comments