Trying out relay with react and ran into this today. Here is what I've done so far.
Root Query:
query {
tasks {
id
taskName
taskStatus
userId
}
}
React component hierarchy
App
↳--TaskList (props: tasks)
↳--TaskListItem (props: task)
Now due to the principle of colocation I know I have to write fragments in each component to describe their data needs.
TaskListItem.js
const TaskListItemContainer = createFragmentContainer(
TaskListItem,
graphql`
fragment TaskListItem_task on task {
id
taskName
taskDone
authorId
}
`
);
TaskList.js
const TaskListContainer = createFragmentContainer(
TaskList,
graphql`
fragment TaskList_tasks on task {
tasks {
...TaskListItem_task
}
}
`
);
App.js
<QueryRenderer
environment={relayEnvironment}
query={graphql`
query AppQuery {
...TaskList_tasks
}
`
}
When I run the relay compiler I get the following error.
Fragment "TaskList_tasks" cannot be spread here as objects of type "Query" can never be of type "task".
App.js (3:15)
2: query AppQuery {
3: ...TaskList_tasks
^
4: }
Not able to figure out how to organize the structure because of this problem. Should I modify the schema just to facilitate the structure and reuse of fragments on the client side?
A basic Fragment consists of five things:
fragment
keywordon
keywordThe selection set is one or more fields of the type you specify that you want to request when you use the Fragment. Think of the Fragment as a drop in replacement for a single selection set. If I have a query like this:
query {
foo
bar
}
then { foo bar }
is the selection set I'm requesting, in this case on the Query
type (or whatever your query root operation type is called in your schema). So if I want to use a fragment, I would write:
query {
...QueryFields
}
fragment QueryFields on Query {
foo
bar
}
In your code, you're trying to write a query like:
query {
...TaskList_tasks
}
However, as the error indicates, the type associated with the TaskList_tasks
fragment is task
. But you're not replacing a selection set for a task
type here, you're replacing a selection set for the Query
type. So your request is not valid.
TLDR; You need to change the type on your Fragment to Query
:
fragment TaskList_tasks on Query {
tasks {
...TaskListItem_task
}
}