#graphql-js #relayjs #relay #relaymodern #react-relay
#graphql-js #relayjs #реле #relaymodern #реагировать-ретранслировать
Вопрос:
Пробовал relay с react и столкнулся с этим сегодня. Вот что я сделал до сих пор.
Корневой запрос:
query {
tasks {
id
taskName
taskStatus
userId
}
}
Иерархия компонентов React
App
↳--TaskList (props: tasks)
↳--TaskListItem (props: task)
Теперь из-за принципа колокации я знаю, что должен писать фрагменты в каждом компоненте, чтобы описать их потребности в данных.
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
}
`
}
Когда я запускаю компилятор реле, я получаю следующую ошибку.
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: }
Не удалось выяснить, как организовать структуру из-за этой проблемы. Должен ли я изменить схему только для облегчения структуры и повторного использования фрагментов на стороне клиента?
Ответ №1:
Базовый фрагмент состоит из пяти вещей:
- ключевое слово
fragment
- имя фрагмента
- ключевое слово
on
- тип, к которому применяется фрагмент
- набор выделений, заключенный в набор фигурных скобок
Набор выбора — это одно или несколько полей указанного вами типа, которые вы хотите запросить при использовании Фрагмента. Думайте о фрагменте как о замене одного набора выбора. Если у меня есть такой запрос:
query {
foo
bar
}
затем { foo bar }
запрашивается набор параметров, который я запрашиваю, в данном случае для Query
типа (или любого другого типа корневой операции вашего запроса, который вызывается в вашей схеме). Поэтому, если я хочу использовать фрагмент, я бы написал:
query {
...QueryFields
}
fragment QueryFields on Query {
foo
bar
}
В вашем коде вы пытаетесь написать запрос типа:
query {
...TaskList_tasks
}
Однако, как указывает ошибка, тип, связанный с TaskList_tasks
фрагментом, является task
. Но вы не заменяете набор выбора для task
типа здесь, вы заменяете набор выбора для Query
типа. Таким образом, ваш запрос недействителен.
TLDR; Вам нужно изменить тип вашего фрагмента на Query
:
fragment TaskList_tasks on Query {
tasks {
...TaskListItem_task
}
}