graphql - GatsbyJS 将用户输入传递给 GraphQL
问题描述
我正在寻找有关从 GatsbyJS 中的表单接受用户输入并将其传递给我的 GraphQL 查询的示例/教程。
我可以在提交时获取用户输入,也可以在测试 graphiql 时传递变量,我只是不知道如何将两者结合起来。
我的数据存储在 Drupal 中,是一个食谱列表。
我希望用户能够输入一种成分,例如鸡肉,然后检索所有以鸡肉为成分的食谱。
我的查询是
query SearchPageQuery($ingredient: String) {
allNodeRecipes(filter: {relationships: {field_ingredients: {elemMatch: {title: {eq: $ingredient}}}}}) {
edges {
node {
id
title
path {
alias
}
relationships {
field_ingredients {
title
}
}
}
}
}
}
解决方案
If I’m understanding your question correctly, the short answer is you can’t, but another approach might work for you.
Gatsby’s GraphQL queries are run in advance as part of the static build of the site, so the data is part of the client-side JavaScript, but the queries have already been run by that point.
This is the same reason you can’t use JavaScript template literals in a StaticQuery:
// This doesn’t work
let myDynamicSlug = 'home'
return (
<StaticQuery
query={graphql`
query ExampleQuery {
examplePage(slug: { eq: ${myDynamicSlug} }) {
title
}
}
`}
render={data => {
console.log(data)
}}
/>
)
You’ll get an error message explaining “String interpolations are not allowed in graphql fragments.” Further reading: https://github.com/gatsbyjs/gatsby/issues/2293
I had a similar problem recently, and I realised it made a lot of sense why you can’t do this. If you are, ex. generating images using the queries in your GraphQL and things akin to that, you can’t pass in client side variables, because all the “static site” Gatsby operations like handling the images have are already done by that time.
What worked for me was to get the larger portion of data I needed in my query, and find what I needed within. In my previous example, that might mean getting allExamplePages
instead of one examplePage
, and then finding the myDynamicSlug
I needed within it:
// This isn’t exactly how you’d hope to be able to do it,
// but it does work for certain problems
let myDynamicSlug = 'home'
return (
<StaticQuery
query={graphql`
query ExampleQuery {
# You might still be able to limit this query, ex. if you know your item
# is within the last 10 items or you don’t need any items before a certain date,
# but if not you might need to query everything
allExamplePages() {
edges {
node {
title
slug
}
}
}
}
`}
render={data => {
// Find and use the item you want, however is appropriate here
data.edges.forEach(item => {
if (item.node.slug === myDynamicSlug) {
console.log(item)
}
})
}}
/>
)
In your case, that hopefully there is an equivalent, ex. looking something up based on the user input. If you can be more specific about the structure of your data, I’d be happy to try and make my suggestion more specific. Hope that helps!
推荐阅读
- php - 如何在加载js之前使用来自url的值设置cookie
- sql - 如果它与当前值相同,则忽略最后一个值
- python - 删除类方法python生成的所有变量(类)
- asp.net - 我可以将会话值传递给变量,然后将其保存到另一个 guid 类型变量吗
- latex - sty 颜色缺失问题 Beamer Poster JHR
- go - 格式字符串中没有占位符
- c# - Xamarin 选项卡式页面选项卡没有填满空间?
- vb.net - 如何以编程方式向我的 Windows 窗体添加一个按钮,单击该按钮将打开一个宏?
- jpa-2.1 - JPQL CreateQuery 与 SYSDate 比较
- javascript - 对数据库的 AJAX 请求