фрагмент не может быть распространен здесь как объекты типа «Запрос»

#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
  }
}