RELAY ENVIRONMENT METHODS
2019-08-18
The Relay Environment exposes a set of methods, which you might find useful, should you ever find yourself contributing to Relay - or just building cool new stuff on your own.
check
environment.check
is used by Relay to determine whether or not a given set of records are present in the store,
which are required to fulfill the provided selector (essentially a normalized query response data signature).
Input signature:
type NormalizationSelector = {|
+dataID: DataID,
+node: NormalizationSelectableNode,
+variables: Variables,
|};
environment.check
returns true
if all required records are present, otherwise false
.
Example usage:
import { getRequest, createOperationDescriptor } from "relay-runtime";
const request = getRequest(query);
const operation = createOperationDescriptor(request, variables);
const canFulfillRequest = environment.check(operation.root);
retain
environment.retain
is handy if you ever need to tell the Relay garbage collection,
to retain some data in a garbage collection cycle.
Input signature:
type NormalizationSelector = {|
+dataID: DataID,
+node: NormalizationSelectableNode,
+variables: Variables,
|};
dataID
is the relay id of the record you want to retain.
environment.retain
returns a disposable, which can be called to discard the record from the list of retained nodes, and schedule a garbage collection cycle.
Example usage:
// with a query
import { getRequest, createOperationDescriptor } from "relay-runtime";
const request = getRequest(query);
const operation = createOperationDescriptor(request, variables);
const retainDisposable = environment.retain(operation.root);
// without a query
const retainDisposable = environment.retain({
dataID,
variables: {},
node: { selections: [] },
});
// cleanup
retainDisposable();
lookup
environment.lookup
returns a snapshot of the most recent data for a given operation.
It is used internally by Relay, as can be seen in the QueryRenderer
render prop,
where the response data snapshot is passed as props
.
Input signature:
type SingularReaderSelector = {|
+kind: "SingularReaderSelector",
+dataID: DataID,
+node: ReaderFragment,
+owner: RequestDescriptor,
+variables: Variables,
|};
Example usage:
import { getRequest, createOperationDescriptor } from "relay-runtime";
const request = getRequest(query);
const operation = createOperationDescriptor(request, variables);
const response = environment.lookup(operation.fragment, operation);
// => response.data
response.data
is of type SelectorData
, which boils down to {[key: string]: mixed}
,
which is essentially just an object of unknown shape.
subscribe
environment.subscribe
subscribes to a provided Snapshot
, like the one returned by environment.lookup
.
The second argument is a callback, which is triggered by the Relay Store whenever there's an update
to the snapshot provided in the first argument.
Upon an update, a new Snapshot
is passed, which could then be used to, say, update a QueryRenderer
.
Input signature:
snapshot: Snapshot,
callback: (snapshot: Snapshot) => void,
environment.subscribe
returns a disposable, which should be called whenever the subscription calls your callback function.
Example usage:
import { getRequest, createOperationDescriptor } from "relay-runtime";
const request = getRequest(query);
const operation = createOperationDescriptor(request, variables);
const response = environment.lookup(operation.fragment, operation);
const subscribeDisposable = environment.subscribe(response, (newSnapshot) => {
// do something with newSnapshot
console.log(newSnapshot.data);
});
// cleanup
subscribeDisposable();
applyUpdate
environment.applyUpdate
as the name implies, applies or commits an update to the Relay Store, very much like commitLocalUpdate
,
except this update will remain rebased on top of the queue until removed.
Input signature:
type OptimisticUpdateFunction = {|
+storeUpdater: (store: RecordSourceProxy) => void,
|};
environment.applyUpdate
returns a disposable, allowing you to revert and dispose any changes made by the storeUpdater
function.
The update is re-applied on each request, so make sure to dispose when it is no longer current.
Example usage:
function storeUpdater(store) {
// do something with store
}
const updaterDisposable = environment.applyUpdate({ storeUpdater });
// revert
updaterDisposable();
revertUpdate
environment.revertUpdate
very intuitively, reverts an optimistic update.
Input signature:
type OptimisticUpdateFunction = {|
+storeUpdater: (store: RecordSourceProxy) => void,
|};
Example usage:
function storeUpdater(store) {
// do something with store
}
// apply
environment.applyUpdate({ storeUpdater });
// revert
environment.revertUpdate(storeUpdater);