Как получить и отобразить элемент по идентификатору с помощью контейнера Relay, Reaction-router и GraphQL
Мне действительно тяжело пытаться разобраться с маршрутами ретрансляции, параметрами реакции-маршрутизатора и сборкой запросов и контейнеров в целом!
Я хочу редактировать функцию, когда пользователь нажимает на конкретную функцию в списке функций. Он передает параметр с именем "id", который является идентификатором компонента в Route.js.
<Route path='/' component={AppComponent} queries={ViewerQuery}>
<IndexRoute component={FeaturesContainer} queries={ViewerQuery} />
<Route path='/feature' component={FeatureComponent} queries={ViewerQuery} />
<Route path="/feature/edit/:id" component={FeatureEditComponent} queries={FeatureQuery}/>
<Redirect from='*' to='/' />
</Route>
В моем файле FeatureQuery у меня есть следующий запрос:
export default {
viewer: (Component) => Relay.QL`
query {
viewer {
${Component.getFragment('viewer')}
}
}
`
};
На данный момент я полностью застрял. Как мне расширить это, чтобы включить "id" и запросить функции, используя "id"? И как будет выглядеть соответствующий фрагмент релейного контейнера? Я вижу только примеры углубления на один уровень.
Я пробовал это, но я знаю, что это неправильно:
export default {
feature: (Component) => Relay.QL`
query {
viewer {
features(id:$id) {
${Component.getFragment('feature')}
}
}
}
`
};
Это текущий релейный контейнер, который получает список функций, как это можно изменить, чтобы он просто возвращал 1 функцию по идентификатору?:
export default Relay.createContainer(CreativeEditComponent, {
fragments: {
viewer: () => Relay.QL`
fragment on User {
id,
features(first: 20) {
edges {
node {
id
name
description
}
}
}
}`
}
});
Я проверил запрос в GraphiQL, и он работает как положено:
query {
viewer {
features(id:"1") {
edges {
node {
id
name
description
}
}
}
}
}
Результат:
{
"data": {
"viewer": {
"features": {
"edges": [
{
"node": {
"id": "Q3JlYXRpdmU6MQ==",
"name": "React",
"description": "A JavaScript library for building user interfaces."
}
}
]
}
}
}
}
schema.js:
const userType = new GraphQLObjectType({
name: 'User',
description: 'A person who uses our app',
fields: () => ({
id: globalIdField('User'),
features: {
type: featureConnection,
description: 'Features that I have',
//args: connectionArgs,
args: {
id: {
type: GraphQLString,
},
after: {
type: GraphQLString,
},
first: {
type: GraphQLInt,
},
before: {
type: GraphQLString,
},
last: {
type: GraphQLInt,
},
},
resolve: (_, args) => {
return resolveGetFeatures(args)
},
},
}),
interfaces: [nodeInterface]
});
const featureType = new GraphQLObjectType({
name: 'Feature',
description: 'Feature integrated in our starter kit',
fields: () => ({
id: globalIdField('Feature'),
name: {
type: GraphQLString,
description: 'Name of the feature'
},
description: {
type: GraphQLString,
description: 'Description of the feature'
}
}),
interfaces: [nodeInterface]
});
1 ответ
Вам необходимо передать переменные маршрутизатора в ваш фрагмент.
const ViewerQuery = {
viewer: (Component, vars) => Relay.QL`
query {
viewer {
${Component.getFragment('viewer', vars)} # <-- this
}
}
`
}
Я скопировал этот код подробно здесь: https://github.com/relay-tools/react-router-relay/issues/92
Затем вы можете использовать переменную id в вашем компоненте, но вам нужно начальное значение для id:
export default Relay.createContainer(CreativeEditComponent, {
initialVariables: {
id: ''
},
fragments: {
viewer: () => Relay.QL`
fragment on User {
id,
feature(id:$id) {
id
name
description
}
}`
}
});
А в schema.js определите поле для вашего типа пользователя, которое обслуживает только одну функцию:
const userType = new GraphQLObjectType({
name: 'User',
description: 'A person who uses our app',
fields: () => ({
id: globalIdField('User'),
feature: {
type: featureType,
description: 'feature',
args: {
id: {
type: GraphQLString,
description: 'The id of the feature'
}
},
resolve: (_, args) => resolveGetFeature (args),
},
...