relay-runtime 20.1.1 → 21.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/experimental.d.ts +34 -0
- package/experimental.js +1 -1
- package/experimental.js.flow +11 -11
- package/handlers/RelayDefaultHandlerProvider.d.ts +12 -0
- package/handlers/connection/ConnectionHandler.d.ts +51 -0
- package/handlers/connection/ConnectionHandler.js.flow +5 -5
- package/handlers/connection/ConnectionInterface.d.ts +40 -0
- package/handlers/connection/ConnectionInterface.js.flow +1 -1
- package/handlers/connection/MutationHandlers.d.ts +17 -0
- package/index.d.ts +274 -0
- package/index.js +1 -1
- package/index.js.flow +125 -62
- package/lib/experimental.js +3 -3
- package/lib/index.js +105 -57
- package/lib/multi-actor-environment/ActorIdentifier.js +2 -2
- package/lib/multi-actor-environment/MultiActorEnvironment.js +3 -1
- package/lib/mutations/commitMutation.js +8 -8
- package/lib/mutations/validateMutation.js +4 -4
- package/lib/query/GraphQLTag.js +3 -3
- package/lib/query/fetchQuery.js +15 -3
- package/lib/store/DataChecker.js +38 -4
- package/lib/store/NormalizationEngine.js +373 -0
- package/lib/store/OperationExecutor.js +172 -113
- package/lib/store/RelayConcreteVariables.js +1 -1
- package/lib/store/RelayErrorTrie.js +2 -2
- package/lib/store/RelayExperimentalGraphResponseTransform.js +8 -8
- package/lib/store/RelayModernEnvironment.js +26 -19
- package/lib/store/RelayModernRecord.js +18 -8
- package/lib/store/RelayModernSelector.js +9 -9
- package/lib/store/RelayModernStore.js +152 -43
- package/lib/store/RelayPublishQueue.js +1 -1
- package/lib/store/RelayReader.js +76 -38
- package/lib/store/RelayRecordSource.js +6 -0
- package/lib/store/RelayReferenceMarker.js +2 -1
- package/lib/store/RelayResponseNormalizer.js +88 -55
- package/lib/store/RelayStoreSubscriptions.js +34 -10
- package/lib/store/RelayStoreUtils.js +8 -1
- package/lib/store/ResolverFragments.js +2 -2
- package/lib/store/live-resolvers/LiveResolverCache.js +25 -9
- package/lib/store/observeFragmentExperimental.js +17 -1
- package/lib/store/observeQueryExperimental.js +2 -2
- package/lib/subscription/requestSubscription.js +3 -3
- package/lib/util/RelayError.js +3 -0
- package/lib/util/RelayFeatureFlags.js +6 -2
- package/lib/util/RelayReplaySubject.js +4 -4
- package/lib/util/handlePotentialSnapshotErrors.js +2 -2
- package/lib/util/stableCopy.js +2 -2
- package/llm-docs/api-reference/entrypoint-apis/entrypoint-container.mdx +38 -0
- package/llm-docs/api-reference/entrypoint-apis/load-entrypoint.mdx +77 -0
- package/llm-docs/api-reference/entrypoint-apis/use-entrypoint-loader.mdx +99 -0
- package/llm-docs/api-reference/graphql/graphql-directives.mdx +378 -0
- package/llm-docs/api-reference/hooks/_use-lazy-load-query-extra.mdx +16 -0
- package/llm-docs/api-reference/hooks/load-query.mdx +84 -0
- package/llm-docs/api-reference/hooks/relay-environment-provider.mdx +78 -0
- package/llm-docs/api-reference/hooks/use-client-query.mdx +65 -0
- package/llm-docs/api-reference/hooks/use-fragment.mdx +69 -0
- package/llm-docs/api-reference/hooks/use-lazy-load-query.mdx +62 -0
- package/llm-docs/api-reference/hooks/use-mutation.mdx +94 -0
- package/llm-docs/api-reference/hooks/use-pagination-fragment.mdx +166 -0
- package/llm-docs/api-reference/hooks/use-prefetchable-forward-pagination-fragment.mdx +134 -0
- package/llm-docs/api-reference/hooks/use-preloaded-query.mdx +84 -0
- package/llm-docs/api-reference/hooks/use-query-loader.mdx +95 -0
- package/llm-docs/api-reference/hooks/use-refetchable-fragment.mdx +122 -0
- package/llm-docs/api-reference/hooks/use-relay-environment.mdx +37 -0
- package/llm-docs/api-reference/hooks/use-subscription.mdx +66 -0
- package/llm-docs/api-reference/relay-resolvers/docblock-format.mdx +321 -0
- package/llm-docs/api-reference/relay-resolvers/runtime-functions.mdx +94 -0
- package/llm-docs/api-reference/relay-runtime/commit-mutation.mdx +65 -0
- package/llm-docs/api-reference/relay-runtime/fetch-query.mdx +118 -0
- package/llm-docs/api-reference/relay-runtime/field-logger.mdx +170 -0
- package/llm-docs/api-reference/relay-runtime/observe-fragment.mdx +92 -0
- package/llm-docs/api-reference/relay-runtime/relay-environment.mdx +53 -0
- package/llm-docs/api-reference/relay-runtime/request-subscription.mdx +54 -0
- package/llm-docs/api-reference/relay-runtime/runtime-configuration.mdx +52 -0
- package/llm-docs/api-reference/relay-runtime/store.mdx +734 -0
- package/llm-docs/api-reference/relay-runtime/wait-for-fragment-data.mdx +89 -0
- package/llm-docs/api-reference/types/CacheConfig.mdx +8 -0
- package/llm-docs/api-reference/types/Disposable.mdx +4 -0
- package/llm-docs/api-reference/types/GraphQLSubscriptionConfig.mdx +17 -0
- package/llm-docs/api-reference/types/MutationConfig.mdx +31 -0
- package/llm-docs/api-reference/types/SelectorStoreUpdater.mdx +6 -0
- package/llm-docs/api-reference/types/UploadableMap.mdx +3 -0
- package/llm-docs/community/learning-resources.mdx +64 -0
- package/llm-docs/debugging/declarative-mutation-directives.mdx +34 -0
- package/llm-docs/debugging/disallowed-id-types-error.mdx +43 -0
- package/llm-docs/debugging/inconsistent-typename-error.mdx +47 -0
- package/llm-docs/debugging/relay-devtools.mdx +73 -0
- package/llm-docs/debugging/why-null.mdx +116 -0
- package/llm-docs/editor-support.mdx +55 -0
- package/llm-docs/error-reference/unknown-field.mdx +36 -0
- package/llm-docs/getting-started/babel-plugin.mdx +31 -0
- package/llm-docs/getting-started/compiler-config.mdx +25 -0
- package/llm-docs/getting-started/compiler.mdx +98 -0
- package/llm-docs/getting-started/lint-rules.mdx +87 -0
- package/llm-docs/getting-started/production.mdx +30 -0
- package/llm-docs/getting-started/quick-start.mdx +216 -0
- package/llm-docs/glossary/glossary.mdx +1040 -0
- package/llm-docs/guided-tour/list-data/advanced-pagination.mdx +157 -0
- package/llm-docs/guided-tour/list-data/connections.mdx +81 -0
- package/llm-docs/guided-tour/list-data/pagination.mdx +193 -0
- package/llm-docs/guided-tour/list-data/rendering-connections.mdx +112 -0
- package/llm-docs/guided-tour/list-data/streaming-pagination.mdx +87 -0
- package/llm-docs/guided-tour/managing-data-outside-react/retaining-queries.mdx +51 -0
- package/llm-docs/guided-tour/refetching/refetching-queries-with-different-data.mdx +337 -0
- package/llm-docs/guided-tour/refetching/refreshing-queries.mdx +350 -0
- package/llm-docs/guided-tour/rendering/environment.mdx +59 -0
- package/llm-docs/guided-tour/rendering/error-states.mdx +295 -0
- package/llm-docs/guided-tour/rendering/fragments.mdx +354 -0
- package/llm-docs/guided-tour/rendering/loading-states.mdx +245 -0
- package/llm-docs/guided-tour/rendering/queries.mdx +261 -0
- package/llm-docs/guided-tour/rendering/variables.mdx +233 -0
- package/llm-docs/guided-tour/reusing-cached-data/fetch-policies.mdx +56 -0
- package/llm-docs/guided-tour/reusing-cached-data/filling-in-missing-data.mdx +102 -0
- package/llm-docs/guided-tour/reusing-cached-data/introduction.mdx +22 -0
- package/llm-docs/guided-tour/reusing-cached-data/presence-of-data.mdx +93 -0
- package/llm-docs/guided-tour/reusing-cached-data/rendering-partially-cached-data.mdx +175 -0
- package/llm-docs/guided-tour/reusing-cached-data/staleness-of-data.mdx +116 -0
- package/llm-docs/guided-tour/updating-data/client-only-data.mdx +115 -0
- package/llm-docs/guided-tour/updating-data/graphql-mutations.mdx +334 -0
- package/llm-docs/guided-tour/updating-data/graphql-subscriptions.mdx +279 -0
- package/llm-docs/guided-tour/updating-data/imperatively-modifying-linked-fields.mdx +511 -0
- package/llm-docs/guided-tour/updating-data/imperatively-modifying-store-data-legacy.mdx +142 -0
- package/llm-docs/guided-tour/updating-data/imperatively-modifying-store-data.mdx +275 -0
- package/llm-docs/guided-tour/updating-data/introduction.mdx +25 -0
- package/llm-docs/guided-tour/updating-data/local-data-updates.mdx +71 -0
- package/llm-docs/guided-tour/updating-data/typesafe-updaters-faq.mdx +83 -0
- package/llm-docs/guided-tour/updating-data/updating-connections.mdx +592 -0
- package/llm-docs/guides/alias-directive.mdx +160 -0
- package/llm-docs/guides/catch-directive.mdx +167 -0
- package/llm-docs/guides/client-schema-extensions.mdx +208 -0
- package/llm-docs/guides/codemods.mdx +79 -0
- package/llm-docs/guides/data-driven-dependencies/client-3d.mdx +255 -0
- package/llm-docs/guides/data-driven-dependencies/configuration.mdx +127 -0
- package/llm-docs/guides/data-driven-dependencies/introduction.mdx +39 -0
- package/llm-docs/guides/data-driven-dependencies/server-3d.mdx +664 -0
- package/llm-docs/guides/document-comparison.mdx +106 -0
- package/llm-docs/guides/graphql-server-specification.mdx +453 -0
- package/llm-docs/guides/network-layer.mdx +69 -0
- package/llm-docs/guides/persisted-queries.mdx +328 -0
- package/llm-docs/guides/relay-resolvers/context.mdx +99 -0
- package/llm-docs/guides/relay-resolvers/defining-fields.mdx +151 -0
- package/llm-docs/guides/relay-resolvers/defining-types.mdx +164 -0
- package/llm-docs/guides/relay-resolvers/deprecated.mdx +27 -0
- package/llm-docs/guides/relay-resolvers/derived-fields.mdx +127 -0
- package/llm-docs/guides/relay-resolvers/descriptions.mdx +44 -0
- package/llm-docs/guides/relay-resolvers/enabling.mdx +41 -0
- package/llm-docs/guides/relay-resolvers/errors.mdx +64 -0
- package/llm-docs/guides/relay-resolvers/field-arguments.mdx +63 -0
- package/llm-docs/guides/relay-resolvers/introduction.mdx +62 -0
- package/llm-docs/guides/relay-resolvers/limitations.mdx +30 -0
- package/llm-docs/guides/relay-resolvers/live-fields.mdx +164 -0
- package/llm-docs/guides/relay-resolvers/return-types.mdx +161 -0
- package/llm-docs/guides/relay-resolvers/suspense.mdx +41 -0
- package/llm-docs/guides/required-directive.mdx +240 -0
- package/llm-docs/guides/semantic-nullability.mdx +93 -0
- package/llm-docs/guides/testing-relay-components.mdx +642 -0
- package/llm-docs/guides/testing-relay-with-preloaded-queries.mdx +160 -0
- package/llm-docs/guides/throw-on-field-error-directive.mdx +58 -0
- package/llm-docs/guides/type-emission.mdx +414 -0
- package/llm-docs/home.mdx +32 -0
- package/llm-docs/principles-and-architecture/architecture-overview.mdx +24 -0
- package/llm-docs/principles-and-architecture/compiler-architecture.mdx +106 -0
- package/llm-docs/principles-and-architecture/runtime-architecture.mdx +249 -0
- package/llm-docs/principles-and-architecture/thinking-in-graphql.mdx +309 -0
- package/llm-docs/principles-and-architecture/thinking-in-relay.mdx +104 -0
- package/llm-docs/principles-and-architecture/videos.mdx +50 -0
- package/llm-docs/tutorial/arrays-lists.mdx +126 -0
- package/llm-docs/tutorial/fragments-1.mdx +487 -0
- package/llm-docs/tutorial/graphql.mdx +172 -0
- package/llm-docs/tutorial/interfaces-polymorphism.mdx +161 -0
- package/llm-docs/tutorial/intro.mdx +58 -0
- package/llm-docs/tutorial/mutations-updates.mdx +624 -0
- package/llm-docs/tutorial/organizing-mutations-queries-and-subscriptions.mdx +13 -0
- package/llm-docs/tutorial/queries-1.mdx +267 -0
- package/llm-docs/tutorial/queries-2.mdx +389 -0
- package/llm-docs/tutorial/refetchable-fragments.mdx +352 -0
- package/multi-actor-environment/ActorIdentifier.d.ts +17 -0
- package/multi-actor-environment/ActorIdentifier.js.flow +2 -2
- package/multi-actor-environment/ActorSpecificEnvironment.js.flow +15 -15
- package/multi-actor-environment/ActorUtils.js.flow +1 -1
- package/multi-actor-environment/MultiActorEnvironment.d.ts +123 -0
- package/multi-actor-environment/MultiActorEnvironment.js.flow +32 -24
- package/multi-actor-environment/MultiActorEnvironmentTypes.d.ts +225 -0
- package/multi-actor-environment/MultiActorEnvironmentTypes.js.flow +6 -6
- package/multi-actor-environment/index.d.ts +14 -0
- package/multi-actor-environment.d.ts +8 -0
- package/mutations/RelayDeclarativeMutationConfig.d.ts +70 -0
- package/mutations/RelayDeclarativeMutationConfig.js.flow +9 -9
- package/mutations/RelayRecordProxy.js.flow +8 -11
- package/mutations/RelayRecordSourceMutator.js.flow +4 -4
- package/mutations/RelayRecordSourceProxy.js.flow +4 -4
- package/mutations/RelayRecordSourceSelectorProxy.js.flow +6 -6
- package/mutations/applyOptimisticMutation.d.ts +25 -0
- package/mutations/applyOptimisticMutation.js.flow +2 -2
- package/mutations/commitLocalUpdate.d.ts +10 -0
- package/mutations/commitMutation.d.ts +48 -0
- package/mutations/commitMutation.js.flow +21 -17
- package/mutations/createUpdatableProxy.js.flow +19 -19
- package/mutations/readUpdatableFragment.js.flow +3 -3
- package/mutations/readUpdatableQuery.js.flow +3 -3
- package/mutations/validateMutation.js.flow +7 -7
- package/network/RelayNetwork.d.ts +12 -0
- package/network/RelayNetworkTypes.d.ts +145 -0
- package/network/RelayNetworkTypes.js.flow +18 -18
- package/network/RelayObservable.d.ts +197 -0
- package/network/RelayObservable.js.flow +32 -30
- package/network/RelayQueryResponseCache.d.ts +16 -0
- package/network/RelayQueryResponseCache.js.flow +3 -3
- package/network/wrapNetworkWithLogObserver.js.flow +1 -1
- package/package.json +2 -1
- package/query/GraphQLTag.d.ts +45 -0
- package/query/GraphQLTag.js.flow +22 -10
- package/query/fetchQuery.d.ts +21 -0
- package/query/fetchQuery.js.flow +23 -10
- package/query/fetchQueryInternal.d.ts +26 -0
- package/query/fetchQueryInternal.js.flow +4 -4
- package/query/fetchQuery_DEPRECATED.d.ts +17 -0
- package/query/fetchQuery_DEPRECATED.js.flow +1 -1
- package/store/ClientID.d.ts +14 -0
- package/store/DataChecker.js.flow +51 -15
- package/store/NormalizationEngine.js.flow +782 -0
- package/store/OperationExecutor.d.ts +51 -0
- package/store/OperationExecutor.js.flow +204 -98
- package/store/RelayConcreteVariables.js.flow +5 -5
- package/store/RelayErrorTrie.js.flow +12 -12
- package/store/RelayExperimentalGraphResponseHandler.js.flow +3 -3
- package/store/RelayExperimentalGraphResponseTransform.js.flow +10 -10
- package/store/RelayModernEnvironment.d.ts +97 -0
- package/store/RelayModernEnvironment.js.flow +58 -43
- package/store/RelayModernFragmentSpecResolver.js.flow +1 -1
- package/store/RelayModernOperationDescriptor.d.ts +28 -0
- package/store/RelayModernOperationDescriptor.js.flow +1 -1
- package/store/RelayModernRecord.d.ts +92 -0
- package/store/RelayModernRecord.js.flow +44 -20
- package/store/RelayModernSelector.d.ts +123 -0
- package/store/RelayModernSelector.js.flow +21 -21
- package/store/RelayModernStore.d.ts +57 -0
- package/store/RelayModernStore.js.flow +219 -58
- package/store/RelayOperationTracker.d.ts +29 -0
- package/store/RelayOperationTracker.js.flow +2 -2
- package/store/RelayOptimisticRecordSource.js.flow +2 -2
- package/store/RelayPublishQueue.js.flow +29 -20
- package/store/RelayReader.js.flow +129 -57
- package/store/RelayRecordSource.d.ts +26 -0
- package/store/RelayRecordSource.js.flow +10 -0
- package/store/RelayRecordState.d.ts +28 -0
- package/store/RelayRecordState.js.flow +1 -1
- package/store/RelayReferenceMarker.js.flow +5 -4
- package/store/RelayResponseNormalizer.d.ts +28 -0
- package/store/RelayResponseNormalizer.js.flow +130 -62
- package/store/RelayStoreSubscriptions.js.flow +52 -8
- package/store/RelayStoreTypes.d.ts +1327 -0
- package/store/RelayStoreTypes.js.flow +371 -278
- package/store/RelayStoreUtils.d.ts +86 -0
- package/store/RelayStoreUtils.js.flow +16 -8
- package/store/ResolverCache.js.flow +2 -2
- package/store/ResolverFragments.d.ts +43 -0
- package/store/ResolverFragments.js.flow +22 -14
- package/store/StoreInspector.js.flow +7 -8
- package/store/ViewerPattern.d.ts +11 -0
- package/store/cloneRelayHandleSourceField.js.flow +1 -1
- package/store/cloneRelayScalarHandleSourceField.js.flow +1 -1
- package/store/createFragmentSpecResolver.d.ts +16 -0
- package/store/createRelayContext.js.flow +1 -1
- package/store/createRelayLoggingContext.js.flow +4 -4
- package/store/defaultGetDataID.js.flow +2 -2
- package/store/isRelayModernEnvironment.d.ts +8 -0
- package/store/isRelayModernEnvironment.js.flow +4 -2
- package/store/live-resolvers/LiveResolverCache.js.flow +55 -20
- package/store/live-resolvers/LiveResolverSuspenseSentinel.js.flow +3 -3
- package/store/live-resolvers/getOutputTypeRecordIDs.js.flow +1 -1
- package/store/live-resolvers/isLiveStateValue.js.flow +2 -2
- package/store/live-resolvers/resolverDataInjector.d.ts +27 -0
- package/store/live-resolvers/resolverDataInjector.js.flow +8 -5
- package/store/observeFragmentExperimental.d.ts +46 -0
- package/store/observeFragmentExperimental.js.flow +50 -21
- package/store/observeQueryExperimental.d.ts +30 -0
- package/store/observeQueryExperimental.js.flow +5 -5
- package/store/readInlineData.d.ts +19 -0
- package/store/readInlineData.js.flow +5 -5
- package/store/waitForFragmentExperimental.d.ts +49 -0
- package/store/waitForFragmentExperimental.js.flow +3 -3
- package/subscription/requestSubscription.d.ts +27 -0
- package/subscription/requestSubscription.js.flow +10 -10
- package/util/JSResourceTypes.flow.js.flow +4 -4
- package/util/NormalizationNode.d.ts +235 -0
- package/util/NormalizationNode.js.flow +127 -123
- package/util/ReaderNode.d.ts +264 -0
- package/util/ReaderNode.js.flow +156 -151
- package/util/RelayConcreteNode.d.ts +120 -0
- package/util/RelayConcreteNode.js.flow +32 -32
- package/util/RelayError.d.ts +13 -0
- package/util/RelayError.js.flow +4 -1
- package/util/RelayFeatureFlags.d.ts +40 -0
- package/util/RelayFeatureFlags.js.flow +21 -1
- package/util/RelayProfiler.d.ts +121 -0
- package/util/RelayProfiler.js.flow +1 -1
- package/util/RelayReplaySubject.d.ts +25 -0
- package/util/RelayReplaySubject.js.flow +3 -3
- package/util/RelayRuntimeTypes.d.ts +59 -0
- package/util/RelayRuntimeTypes.js.flow +36 -33
- package/util/createPayloadFor3DField.d.ts +17 -0
- package/util/createPayloadFor3DField.js.flow +9 -5
- package/util/deepFreeze.d.ts +8 -0
- package/util/deepFreeze.js.flow +2 -2
- package/util/getFragmentIdentifier.d.ts +10 -0
- package/util/getFragmentIdentifier.js.flow +1 -1
- package/util/getPaginationMetadata.d.ts +20 -0
- package/util/getPaginationMetadata.js.flow +1 -1
- package/util/getPaginationVariables.d.ts +20 -0
- package/util/getPaginationVariables.js.flow +1 -1
- package/util/getPendingOperationsForFragment.d.ts +18 -0
- package/util/getPendingOperationsForFragment.js.flow +2 -2
- package/util/getRefetchMetadata.d.ts +19 -0
- package/util/getRefetchMetadata.js.flow +6 -5
- package/util/getRelayHandleKey.d.ts +8 -0
- package/util/getRequestIdentifier.d.ts +17 -0
- package/util/getValueAtPath.d.ts +8 -0
- package/util/getValueAtPath.js.flow +3 -3
- package/util/handlePotentialSnapshotErrors.d.ts +14 -0
- package/util/handlePotentialSnapshotErrors.js.flow +5 -5
- package/util/isEmptyObject.js.flow +1 -1
- package/util/isPromise.d.ts +8 -0
- package/util/isPromise.js.flow +2 -2
- package/util/isScalarAndEqual.d.ts +8 -0
- package/util/isScalarAndEqual.js.flow +1 -1
- package/util/recycleNodesInto.d.ts +8 -0
- package/util/recycleNodesInto.js.flow +2 -2
- package/util/registerEnvironmentWithDevTools.js.flow +1 -1
- package/util/shallowFreeze.js.flow +1 -1
- package/util/stableCopy.d.ts +8 -0
- package/util/stableCopy.js.flow +5 -5
- package/util/withProvidedVariables.d.ts +19 -0
- package/util/withProvidedVariables.js.flow +14 -10
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: imperatively-modifying-store-data
|
|
3
|
+
title: Imperatively modifying store data
|
|
4
|
+
slug: /guided-tour/updating-data/imperatively-modifying-store-data/
|
|
5
|
+
description: Using readUpdatableQuery to update scalar fields in the store
|
|
6
|
+
keywords:
|
|
7
|
+
- record source
|
|
8
|
+
- store
|
|
9
|
+
- updater
|
|
10
|
+
- typesafe updaters
|
|
11
|
+
- readUpdatableQuery
|
|
12
|
+
- readUpdatableFragment
|
|
13
|
+
- updatable
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
import DocsRating from '@site/src/core/DocsRating';
|
|
17
|
+
import {OssOnly, FbInternalOnly} from 'docusaurus-plugin-internaldocs-fb/internal';
|
|
18
|
+
|
|
19
|
+
:::note
|
|
20
|
+
See also [this guide on updating linked fields in the store](../imperatively-modifying-linked-fields).
|
|
21
|
+
:::
|
|
22
|
+
|
|
23
|
+
Data in Relay stores can be imperatively modified within updater functions.
|
|
24
|
+
|
|
25
|
+
## When to use updaters
|
|
26
|
+
|
|
27
|
+
### Complex client updates
|
|
28
|
+
|
|
29
|
+
You might provide an updater function if the changes to local data are more complex than what can be achieved by simply writing a network response to the store and cannot be handled by the declarative mutation directives.
|
|
30
|
+
|
|
31
|
+
### Client schema extensions
|
|
32
|
+
|
|
33
|
+
In addition, since the network response necessarily will not include data for fields defined in client schema extensions, you may wish to use an updater to initialize data defined in client schema extensions.
|
|
34
|
+
|
|
35
|
+
### Use of other APIs
|
|
36
|
+
|
|
37
|
+
Lastly, there are things you can only achieve using updaters, such as invalidating nodes, deleting nodes, finding all connections at a given field, etc.
|
|
38
|
+
|
|
39
|
+
### If multiple optimistic responses modify a given store value
|
|
40
|
+
|
|
41
|
+
If two optimistic responses affect a given value, and the first optimistic response is rolled back, the second one will remain applied.
|
|
42
|
+
|
|
43
|
+
For example, if two optimistic responses each increase a story's like count by one, and the first optimistic response is rolled back, the second optimistic response remains applied. However, it is **not recalculated**, and the value of the like count will remain increased by two.
|
|
44
|
+
|
|
45
|
+
## When **not** to use updaters
|
|
46
|
+
|
|
47
|
+
### To trigger other side effects
|
|
48
|
+
|
|
49
|
+
You should use the `onCompleted` callback to trigger other side effects. `onCompleted` callbacks are guaranteed to be called once, but updaters and optimistic updaters can be called repeatedly.
|
|
50
|
+
|
|
51
|
+
## The various types of updater functions
|
|
52
|
+
|
|
53
|
+
The `useMutation` and `commitMutation` APIs accept configuration objects which can include `optimisticUpdater` and `updater` fields. The `requestSubscription` and `useSubscription` APIs accept configuration objects which can include `updater` fields.
|
|
54
|
+
|
|
55
|
+
In addition, there is another API (`commitLocalUpdate`) which also accepts an updater function. It will be discussed in the [Other APIs for modifying local data](../local-data-updates/) section.
|
|
56
|
+
|
|
57
|
+
## Optimistic updaters vs updaters
|
|
58
|
+
|
|
59
|
+
Mutations can have both optimistic and regular updaters. Optimistic updaters are executed when a mutation is triggered. When that mutation completes or errors, the optimistic update is rolled back.
|
|
60
|
+
|
|
61
|
+
Regular updaters are executed when a mutation completes successfully.
|
|
62
|
+
|
|
63
|
+
## Example
|
|
64
|
+
|
|
65
|
+
Let's construct an example in which an `is_new_comment` field (which is defined in a schema extension) is set to `true` on a newly created Feedback object in a mutation updater.
|
|
66
|
+
|
|
67
|
+
```graphql
|
|
68
|
+
# Feedback.graphql
|
|
69
|
+
extend type Feedback {
|
|
70
|
+
is_new_comment: Boolean
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
```js
|
|
75
|
+
// CreateFeedback.js
|
|
76
|
+
import type {Environment} from 'react-relay';
|
|
77
|
+
import type {
|
|
78
|
+
FeedbackCreateData,
|
|
79
|
+
CreateFeedbackMutation,
|
|
80
|
+
CreateFeedbackMutation$data,
|
|
81
|
+
} from 'CreateFeedbackMutation.graphql';
|
|
82
|
+
|
|
83
|
+
const {commitMutation, graphql} = require('react-relay');
|
|
84
|
+
const {ConnectionHandler} = require('relay-runtime');
|
|
85
|
+
|
|
86
|
+
function commitCreateFeedbackMutation(
|
|
87
|
+
environment: Environment,
|
|
88
|
+
input: FeedbackCreateData,
|
|
89
|
+
) {
|
|
90
|
+
return commitMutation<FeedbackCreateData>(environment, {
|
|
91
|
+
mutation: graphql`
|
|
92
|
+
mutation CreateFeedbackMutation($input: FeedbackCreateData!) {
|
|
93
|
+
feedback_create(input: $input) {
|
|
94
|
+
feedback {
|
|
95
|
+
id
|
|
96
|
+
# Step 1: in the mutation response, spread an updatable fragment (defined below).
|
|
97
|
+
# This updatable fragment will select the fields that we want to update on this
|
|
98
|
+
# particular feedback object.
|
|
99
|
+
...CreateFeedback_updatable_feedback
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
`,
|
|
104
|
+
variables: {input},
|
|
105
|
+
|
|
106
|
+
// Step 2: define an updater
|
|
107
|
+
updater: (store: RecordSourceSelectorProxy, response: ?CreateCommentMutation$data) => {
|
|
108
|
+
// Step 3: Access and nullcheck the feedback object.
|
|
109
|
+
// Note that this could also have been achieved with the @required directive.
|
|
110
|
+
const feedbackRef = response?.feedback_create?.feedback;
|
|
111
|
+
if (feedbackRef == null) {
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Step 3: call store.readUpdatableFragment
|
|
116
|
+
const {updatableData} = store.readUpdatableFragment(
|
|
117
|
+
// Step 4: Pass it a fragment literal, where the fragment contains the @updatable directive.
|
|
118
|
+
// This fragment selects the fields that you wish to update on the feedback object.
|
|
119
|
+
// In step 1, we spread this fragment in the query response.
|
|
120
|
+
graphql`
|
|
121
|
+
fragment CreateFeedback_updatable_feedback on Feedback @updatable {
|
|
122
|
+
is_new_comment
|
|
123
|
+
}
|
|
124
|
+
`,
|
|
125
|
+
// Step 5: Pass the fragment reference.
|
|
126
|
+
feedbackRef
|
|
127
|
+
);
|
|
128
|
+
|
|
129
|
+
// Step 6: Mutate the updatableData object!
|
|
130
|
+
updatableData.is_new_comment = true;
|
|
131
|
+
},
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
module.exports = {commit: commitCreateFeedbackMutation};
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Let's distill what's going on here.
|
|
139
|
+
|
|
140
|
+
* The `updater` accepts two parameters: a `RecordSourceSelectorProxy` and an optional object that is the result of reading out the mutation response.
|
|
141
|
+
* The type of this second argument is a nullable version of the `$data` type that is imported from the generated mutation file.
|
|
142
|
+
* The second argument contains just the data selected directly by the mutation argument. In other words, it will not contain any fields selected solely by spread fragments.
|
|
143
|
+
* This `updater` is executed after the mutation response has been written to the store.
|
|
144
|
+
* In this example updater, we do three things:
|
|
145
|
+
* First, we spread an updatable fragment in the mutation response.
|
|
146
|
+
* Second, we read out the fields selected by this fragment by calling `readUpdatableFragment`. This returns an updatable proxy object.
|
|
147
|
+
* Third, we update fields on this updatable proxy.
|
|
148
|
+
* Once this updater completes, the updates that have been recorded are written to the store, and all affected components are re-rendered.
|
|
149
|
+
|
|
150
|
+
## Example 2: Updating data in response to user interactions
|
|
151
|
+
|
|
152
|
+
Let's consider the common case of updating store data in response to a user interaction. In a click handler, let's a toggle an `is_selected` field. This field is defined on Users in a client schema extension.
|
|
153
|
+
|
|
154
|
+
```graphql
|
|
155
|
+
# User.graphql
|
|
156
|
+
extend type User {
|
|
157
|
+
is_selected: Boolean
|
|
158
|
+
}
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
```js
|
|
162
|
+
// UserSelectToggle.react.js
|
|
163
|
+
import type {RecordSourceSelectorProxy} from 'react-relay';
|
|
164
|
+
import type {UserSelectToggle_viewer$key} from 'UserSelectToggle_viewer.graphql';
|
|
165
|
+
|
|
166
|
+
const {useRelayEnvironment, commitLocalUpdate} = require('react-relay');
|
|
167
|
+
|
|
168
|
+
function UserSelectToggle({ userId, viewerRef }: {
|
|
169
|
+
userId: string,
|
|
170
|
+
viewerRef: UserSelectToggle_viewer$key,
|
|
171
|
+
}) {
|
|
172
|
+
const viewer = useFragment(graphql`
|
|
173
|
+
fragment UserSelectToggle_viewer on Viewer {
|
|
174
|
+
user(user_id: $user_id) {
|
|
175
|
+
id
|
|
176
|
+
name
|
|
177
|
+
is_selected
|
|
178
|
+
...UserSelectToggle_updatable_user
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
`, viewerRef);
|
|
182
|
+
|
|
183
|
+
const environment = useRelayEnvironment();
|
|
184
|
+
|
|
185
|
+
return <button
|
|
186
|
+
onClick={() => {
|
|
187
|
+
commitLocalUpdate(
|
|
188
|
+
environment,
|
|
189
|
+
(store: RecordSourceSelectorProxy) => {
|
|
190
|
+
const userRef = viewer.user;
|
|
191
|
+
if (userRef == null) {
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
const {updatableData} = store.readUpdatableFragment(
|
|
196
|
+
graphql`
|
|
197
|
+
fragment UserSelectToggle_updatable_user on User @updatable {
|
|
198
|
+
is_selected
|
|
199
|
+
}
|
|
200
|
+
`,
|
|
201
|
+
userRef
|
|
202
|
+
);
|
|
203
|
+
|
|
204
|
+
updatableData.is_selected = !viewer?.user?.is_selected;
|
|
205
|
+
}
|
|
206
|
+
);
|
|
207
|
+
}}
|
|
208
|
+
>
|
|
209
|
+
{viewer?.user?.is_selected ? 'Deselect' : 'Select'} {viewer?.user?.name}
|
|
210
|
+
</button>
|
|
211
|
+
}
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
Let's distill what's going on here.
|
|
215
|
+
|
|
216
|
+
* In a click handler, we call `commitLocalUpdate`, which accepts a Relay environment and an updater function. **Unlike in the previous examples, this updater does not accept a second parameter** because there is no associated network payload.
|
|
217
|
+
* In this updater function, we access get an updatable proxy object by calling `store.readUpdatableFragment`, and toggle the `is_selected` field.
|
|
218
|
+
* Like the previous example in which we called `readUpdatableFragment`, this can be rewritten to use the `readUpdatableQuery` API.
|
|
219
|
+
|
|
220
|
+
:::note
|
|
221
|
+
This example can be rewritten using the `environment.commitPayload` API, albeit without type safety.
|
|
222
|
+
:::
|
|
223
|
+
|
|
224
|
+
## Alternative API: `readUpdatableQuery`.
|
|
225
|
+
|
|
226
|
+
In the previous examples, we used an updatable fragment to access the record whose fields we want to update. This can also be possible to do with an updatable query.
|
|
227
|
+
|
|
228
|
+
If we know the path from the root (i.e. the object whose type is `Query`) to the record we wish to modify, we can use the `readUpdatableQuery` API to achieve this.
|
|
229
|
+
|
|
230
|
+
For example, we could set the viewer's `name` field in response to an event as follows:
|
|
231
|
+
|
|
232
|
+
```js
|
|
233
|
+
// NameUpdater.react.js
|
|
234
|
+
function NameUpdater({ queryRef }: {
|
|
235
|
+
queryRef: NameUpdater_viewer$key,
|
|
236
|
+
}) {
|
|
237
|
+
const environment = useRelayEnvironment();
|
|
238
|
+
const data = useFragment(
|
|
239
|
+
graphql`
|
|
240
|
+
fragment NameUpdater_viewer on Viewer {
|
|
241
|
+
name
|
|
242
|
+
}
|
|
243
|
+
`,
|
|
244
|
+
queryRef
|
|
245
|
+
);
|
|
246
|
+
const [newName, setNewName] = useState(data?.viewer?.name);
|
|
247
|
+
const onSubmit = () => {
|
|
248
|
+
commitLocalUpdate(environment, store => {
|
|
249
|
+
const {updatableData} = store.readUpdatableQuery(
|
|
250
|
+
graphql`
|
|
251
|
+
query NameUpdaterUpdateQuery @updatable {
|
|
252
|
+
viewer {
|
|
253
|
+
name
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
`,
|
|
257
|
+
{}
|
|
258
|
+
);
|
|
259
|
+
const viewer = updatableData.viewer;
|
|
260
|
+
if (viewer != null) {
|
|
261
|
+
viewer.name = newName;
|
|
262
|
+
}
|
|
263
|
+
});
|
|
264
|
+
};
|
|
265
|
+
|
|
266
|
+
// etc
|
|
267
|
+
}
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
* This particular example can be rewritten using `readUpdatableFragment`. However, you may prefer `readUpdatableQuery` for several reasons:
|
|
271
|
+
* You do not have ready access to a fragment reference, e.g. if the call to `commitLocalUpdate` is not obviously associated with a component.
|
|
272
|
+
* You do not have ready access to a fragment where we select the **parent record** of the record we wish to modify (e.g. the `Query` in this example). Due to a known type hole in Relay, **updatable fragments cannot be spread at the top level.**
|
|
273
|
+
* You wish to use variables in the updatable fragment. Currently, updatable fragments reuse the variables that were passed to the query. This means that you cannot, for example, have an updatable fragment with fragment-local variables and call `readUpdatableFragment` multiple times, each time passing different variables.
|
|
274
|
+
|
|
275
|
+
<DocsRating />
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: introduction
|
|
3
|
+
title: Introduction
|
|
4
|
+
slug: /guided-tour/updating-data/introduction
|
|
5
|
+
description: Relay guide to updating data
|
|
6
|
+
keywords:
|
|
7
|
+
- updating
|
|
8
|
+
- mutation
|
|
9
|
+
- useMutation
|
|
10
|
+
- commitMutation
|
|
11
|
+
- relay store
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
import DocsRating from '@site/src/core/DocsRating';
|
|
15
|
+
import {OssOnly, FbInternalOnly} from 'docusaurus-plugin-internaldocs-fb/internal';
|
|
16
|
+
|
|
17
|
+
In the Fetching Data section, we discuss how to fetch data using GraphQL queries. Though fetching data can have the *incidental* effect of modifying data in Relay's local store (if the fetched data has changed), we haven't discussed any ways to *intentionally* modify our locally stored data.
|
|
18
|
+
|
|
19
|
+
This section will do just that: it will discuss how to update our local data store, and data on the server.
|
|
20
|
+
|
|
21
|
+
:::note
|
|
22
|
+
The **Relay store** is a cache of GraphQL data, associated with a given Relay environment, that we have encountered during the execution of an application.
|
|
23
|
+
:::
|
|
24
|
+
|
|
25
|
+
<DocsRating />
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: local-data-updates
|
|
3
|
+
title: Local Data Updates
|
|
4
|
+
slug: /guided-tour/updating-data/local-data-updates/
|
|
5
|
+
description: Other APIs for modifying store data
|
|
6
|
+
keywords:
|
|
7
|
+
- client-only
|
|
8
|
+
- commitLocalUpdate
|
|
9
|
+
- commitPayload
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
import DocsRating from '@site/src/core/DocsRating';
|
|
13
|
+
import {OssOnly, FbInternalOnly} from 'docusaurus-plugin-internaldocs-fb/internal';
|
|
14
|
+
// @fb-only
|
|
15
|
+
|
|
16
|
+
There are a couple of APIs that Relay provides in order to make purely local updates to the Relay store (i.e. updates not tied to a server operation).
|
|
17
|
+
|
|
18
|
+
Note that local data updates can be made both on [client-only data](../client-only-data/), or on regular data that was fetched from the server via an operation.
|
|
19
|
+
|
|
20
|
+
## commitLocalUpdate
|
|
21
|
+
|
|
22
|
+
To make updates using an [`updater`](../imperatively-modifying-store-data/) function, you can use the `commitLocalUpdate` API:
|
|
23
|
+
|
|
24
|
+
```js
|
|
25
|
+
import type {Environment} from 'react-relay';
|
|
26
|
+
|
|
27
|
+
const {commitLocalUpdate, graphql} = require('react-relay');
|
|
28
|
+
|
|
29
|
+
function commitCommentCreateLocally(
|
|
30
|
+
environment: Environment,
|
|
31
|
+
feedbackID: string,
|
|
32
|
+
) {
|
|
33
|
+
return commitLocalUpdate(environment, store => {
|
|
34
|
+
// Imperatively mutate the store here
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
module.exports = {commit: commitCommentCreateLocally};
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
* `commitLocalUpdate` update simply takes an environment and an updater function.
|
|
42
|
+
* `updater` takes a *`store`* argument, which is an instance of a [`RecordSourceSelectorProxy`](../../../api-reference/store/); this interface allows you to *imperatively* write and read data directly to and from the Relay store. This means that you have full control over how to update the store: you can *create entirely new records*, or *update or delete existing ones*.
|
|
43
|
+
* Unlike regular and optimistic updaters that are accepted by the mutation and subscription APIs, the updater passed to `commitLocalUpdate` does not accept a second parameter. This is because there is no associated network response.
|
|
44
|
+
* Note that any local data updates will automatically cause components subscribed to the data to be notified of the change and re-render.
|
|
45
|
+
|
|
46
|
+
## commitPayload
|
|
47
|
+
|
|
48
|
+
`commitPayload` takes an `OperationDescriptor` and the payload for the query, and writes it to the Relay Store. The payload will be resolved like a normal server response for a query, and will also resolve Data Driven Dependencies that are passed as `JSResource`, `requireDefer`, etc.
|
|
49
|
+
|
|
50
|
+
```js
|
|
51
|
+
import type {FooQueryRawResponse} from 'FooQuery.graphql'
|
|
52
|
+
|
|
53
|
+
const {createOperationDescriptor} = require('relay-runtime');
|
|
54
|
+
|
|
55
|
+
const operationDescriptor = createOperationDescriptor(FooQuery, {
|
|
56
|
+
id: 'an-id',
|
|
57
|
+
otherVariable: 'value',
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
const payload: FooQueryRawResponse = {...};
|
|
61
|
+
|
|
62
|
+
environment.commitPayload(operationDescriptor, payload);
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
* An `OperationDescriptor` can be created by `createOperationDescriptor`; it takes the query and the query variables.
|
|
66
|
+
* The payload can be typed using the Flow type generated by adding the directive `@raw_response_type` to the query.
|
|
67
|
+
* Note that any local data updates will automatically cause components subscribed to the data to be notified of the change and re-render.
|
|
68
|
+
|
|
69
|
+
// @fb-only
|
|
70
|
+
|
|
71
|
+
<DocsRating />
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: typesafe-updaters-faq
|
|
3
|
+
title: Typesafe updaters FAQ
|
|
4
|
+
slug: /guided-tour/updating-data/typesafe-updaters-faq/
|
|
5
|
+
description: Typesafe updater FAQ
|
|
6
|
+
keywords:
|
|
7
|
+
- typesafe updaters
|
|
8
|
+
- readUpdatableQuery
|
|
9
|
+
- readUpdatableFragment
|
|
10
|
+
- updater
|
|
11
|
+
- updatable
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
import DocsRating from '@site/src/core/DocsRating';
|
|
15
|
+
import {OssOnly, FbInternalOnly} from 'docusaurus-plugin-internaldocs-fb/internal';
|
|
16
|
+
|
|
17
|
+
# Typesafe Updaters FAQ
|
|
18
|
+
|
|
19
|
+
<FbInternalOnly>
|
|
20
|
+
|
|
21
|
+
:::note
|
|
22
|
+
|
|
23
|
+
Is something missing from this Q&A? Are you confused? Would you like help adopting these APIs? Please, reach out to [Robert Balicki](https://fb.workplace.com/profile.php?id=100042823931887). I am happy to help!
|
|
24
|
+
|
|
25
|
+
:::
|
|
26
|
+
|
|
27
|
+
</FbInternalOnly>
|
|
28
|
+
|
|
29
|
+
# General
|
|
30
|
+
|
|
31
|
+
## What is typesafe updaters?
|
|
32
|
+
|
|
33
|
+
Typesafe updaters is the name given to a project to provide a typesafe and ergonomic alternative to the existing APIs for imperatively updating data in the Relay store.
|
|
34
|
+
|
|
35
|
+
For example, [`readUpdatableFragment`](../../../api-reference/store/#readupdatablefragmentfragment-updatablefragmenttfragmenttype-tdatafragmentreference-hasupdatablespreadtfragmenttype-updatabledatatdata) and [`readUpdatableQuery`](../../../api-reference/store/#readupdatablequeryquery-updatablequerytvariables-tdatavariables-tvariables-updatabledatatdata) are two typesafe updaters that the store exposes.
|
|
36
|
+
|
|
37
|
+
## Why?
|
|
38
|
+
|
|
39
|
+
Relay provides typesafe and ergonomic APIs for fetching and managing data that originates on the server. In addition, Relay provides the ability to define local-only fields in **client schema extensions**. However, the APIs for mutating the data in these fields has hitherto been verbose and not ergonomic, meaning that we could not recommend Relay as a solution for managing local state.
|
|
40
|
+
|
|
41
|
+
## What was wrong with the existing APIs?
|
|
42
|
+
|
|
43
|
+
The pre-existing APIs are verbose and not typesafe. They make it easy to make a variety of mistakes and require that the developer understand a new set of APIs only when writing updaters.
|
|
44
|
+
|
|
45
|
+
Typesafe updaters is a set of APIs that are typesafe and more ergonomic. They leverage well-known Relay idioms (queries, fragments, type refinement) and use getters and setters instead of requiring that the developer learn about a set of methods that are unused elsewhere.
|
|
46
|
+
|
|
47
|
+
## How does a developer use typesafe updaters?
|
|
48
|
+
|
|
49
|
+
With typesafe updaters, a developers writes an updatable query or a fragment that specifies the data to imperatively update. Then, the developer reads out that data from the store, returning a so-called **updatable proxy**. Then, the developer mutates that updatable proxy. Mutating that updatable proxy using setters (e.g. `updatableData.name = "Godzilla"`) results in calls to the old API, but with added type safety.
|
|
50
|
+
|
|
51
|
+
## What is an updatable query or fragment?
|
|
52
|
+
|
|
53
|
+
An updatable query or fragment is a query or fragment that has the `@updatable` directive.
|
|
54
|
+
|
|
55
|
+
# Updatable queries and fragments are not fetched
|
|
56
|
+
|
|
57
|
+
## Are fields selected in updatable queries and fragments fetched from the server?
|
|
58
|
+
|
|
59
|
+
No! The server doesn't know about updatable queries and fragments. Their fields are never fetched.
|
|
60
|
+
|
|
61
|
+
Even if you spread an updatable fragment in a regular query or fragment, the fields selected by that updatable fragment are not fetched as part of that request.
|
|
62
|
+
|
|
63
|
+
## What if I want to fetch a field and also mutate it?
|
|
64
|
+
|
|
65
|
+
You should select that field in both a regular query/fragment **and** in an updatable query/fragment.
|
|
66
|
+
|
|
67
|
+
## What are some consequences of this?
|
|
68
|
+
|
|
69
|
+
* When you read out updatable data, it can be missing if it isn't present in the store.
|
|
70
|
+
* You cannot spread regular fragments in updatable queries/fragments.
|
|
71
|
+
* The generated artifact for updatable queries/fragments does not contain a query ID and does not contain a normalization AST (which is used for writing network data to the store.)
|
|
72
|
+
* Directives like `@defer`, etc. do not make sense in this context, and are disallowed.
|
|
73
|
+
|
|
74
|
+
# Misc
|
|
75
|
+
|
|
76
|
+
## Where do I get a `store`?
|
|
77
|
+
|
|
78
|
+
The classes `RelayRecordSourceSelectorProxy`, `RecordSourceProxy` and `RelayRecordSourceProxy` contain the methods `readUpdatableQuery` and `readUpdatableFragment`. One can acquire an instance of these classes:
|
|
79
|
+
|
|
80
|
+
* In updaters of mutations and subscriptions
|
|
81
|
+
* In optimistic updaters of mutations
|
|
82
|
+
* When using `RelayModernEnvironment`'s `commitUpdate`, `applyUpdate`, etc. methods.
|
|
83
|
+
* When using the standalone `commitLocalUpdate` method.
|