I have a component, with:
useFragment reading list of elements
- mutation pushing a new element in updater
// IN RENDER:
const mediaListCollection = useFragment(
graphql`
fragment AddToList_mediaListCollection on MediaListCollection {
lists {
...AddToList_updatable
status
entries {
id
...AddToList_assignable
}
}
}
`,
mediaListCollectionKey
)
// MUTATION:
{
updater: (store, response) => {
for (const list of mediaListCollection.lists ?? []) {
if (list != null && list.status === source.status) {
const { updatableData } =
store.readUpdatableFragment<AddToList_updatable$key>(
graphql`
fragment AddToList_updatable on MediaListGroup @updatable {
entries {
id
...AddToList_assignable
}
}
`,
list
)
if (response?.SaveMediaListEntry != null) {
updatableData.entries = [
...(list.entries?.filter((entry) => entry != null) ?? []),
response.SaveMediaListEntry,
]
}
}
}
}
}
I've noticed useFragment is causing performance issue and it doesn't have to read during render so I've moved it into the updater.
// AFTER REFACTOR:
{
updater: (store, response) => {
const { updatableData: mediaListCollection } =
store.readUpdatableFragment<AddToList_mediaListCollection$key>(
graphql`
fragment AddToList_mediaListCollection on MediaListCollection
@updatable {
lists {
status
entries {
id
...AddToList_assignable
}
}
}
`,
mediaListCollectionKey
)
for (const list of mediaListCollection.lists ?? []) {
if (list != null && list.status === source.status) {
if (response?.SaveMediaListEntry != null) {
list.entries = [
...(list.entries?.filter((entry) => entry != null) ?? []),
response.SaveMediaListEntry,
]
}
}
}
}
}
But now I get a type error when setting:
Type '{ readonly id: string; } | null | undefined' is not assignable to type '{ readonly __typename: "MediaList"; readonly __id: string; readonly " $fragmentSpreads": FragmentRefs<"AddToList_assignable">; }'.
New generated type is missing __typename and __id fields:
export type AddToList_mediaListCollection$data = {
get lists(): ReadonlyArray<{
status: MediaListStatus | null | undefined;
get entries(): ReadonlyArray<{
readonly id: string; // <-- HERE ONLY ID IS GENERATED
} | null | undefined> | null | undefined;
set entries(value: ReadonlyArray<{
readonly __typename: "MediaList";
readonly __id: string;
readonly " $fragmentSpreads": FragmentRefs<"AddToList_assignable">;
}>);
} | null | undefined> | null | undefined;
set lists(value: []);
readonly " $fragmentType": "AddToList_mediaListCollection";
};
The OLD one is:
export type AddToList_mediaListCollection$data = {
readonly lists: ReadonlyArray<{
readonly $updatableFragmentSpreads: FragmentRefs<"AddToList_updatable">;
readonly entries: ReadonlyArray<{
readonly __typename: "MediaList";
readonly __id: string;
readonly id: string;
readonly " $fragmentSpreads": FragmentRefs<"AddToList_assignable">;
} | null | undefined> | null | undefined;
readonly status: MediaListStatus | null | undefined;
} | null | undefined> | null | undefined;
readonly " $fragmentType": "AddToList_mediaListCollection";
};
There's an easy workaround by selecting these missing fields manually
This makes it work without runtime error, just the typescript error because the AddToList_assignable spread is missing
relay-compiler: 21.0.1
I have a component, with:
useFragmentreading list of elementsI've noticed
useFragmentis causing performance issue and it doesn't have to read during render so I've moved it into the updater.But now I get a type error when setting:
New generated type is missing
__typenameand__idfields:The OLD one is:
There's an easy workaround by selecting these missing fields manually
This makes it work without runtime error, just the typescript error because the
AddToList_assignablespread is missingrelay-compiler: 21.0.1