我有一个测试relay-starter-kit项目,其中包含一个自动填充搜索表单,可以向浏览器显示引号。当我使用搜索表单时,我在浏览器中收到错误" app.js:8284 Uncaught TypeError:无法读取属性' edge'未定义"。我无法理解为什么它第一次填充搜索字段而不是在搜索表单中输入。值得注意的是,如果您对searchTerm变量进行硬编码,它将呈现搜索结果。换句话说,它可以在硬编码时读取边缘。对此的任何指导都会很棒。感谢。
架构为here 这是搜索词的有效graphql查询不会呈现的组件。
import React from 'react';
import Relay from 'react-relay';
import { debounce } from 'lodash';
import SearchForm from '../search-form';
import Quote from '../quote';
class App extends React.Component {
constructor(props) {
super(props)
this.search = debounce(this.search.bind(this), 300)
}
search(searchTerm) {
this.props.relay.setVariables({ searchTerm });
}
render() {
return (
<div className="quotes-library">
<SearchForm searchAction={this.search} />
<div className="quotes-list">
{this.props.viewer.quotes.edges.map(edge =>
<Quote key={edge.node.id} quote={edge.node} />
)}
</div>
</div>
)
}
}
export default Relay.createContainer(App, {
initialVariables: {
searchTerm: '',
},
fragments: {
viewer: () => Relay.QL`
fragment on User {
quotes(first:100, searchTerm: $searchTerm) {
edges {
node {
id
${Quote.getFragment('quote')}
}
}
}
}
`,
},
});
更新:这是Chrome DevTools网络标签中显示的查询。请注意&#39; p&#39;正在查询对搜索表单的输入。
query App_ViewerRelayQL($id_0:ID!) {
node(id:$id_0) {
...F2
}
}
fragment F0 on Quote {
id,
likesCount
}
fragment F1 on Quote {
text,
author,
id,
...F0
}
fragment F2 on User {
_quotes3UfnML:quotes(first:100,searchTerm:"pri") {
edges {
node {
id,
...F1
},
cursor
},
pageInfo {
hasNextPage,
hasPreviousPage
}
},
id
}
将console.log添加到render()会显示searchTerm输入:
app.js:17
{
"viewer": {
"__dataID__": "VXNlcjox",
"__status__": 4
},
"relay": {
"pendingVariables": null,
"route": {
"name": "AppHomeRoute",
"params": {},
"queries": {}
},
"variables": {
"searchTerm": "pri"
}
}
}
app.js第24行发生以下错误,即{this.props.library.quotes.edges.map(edge =>
<Quote key={edge.node.id} quote={edge.node} />
)}
:
app.js:8285 Uncaught TypeError: Cannot read property 'edges' of undefined
at App.render (app.js:8285)
at app.js:43197
at measureLifeCyclePerf (app.js:42476)
at ReactCompositeComponentWrapper._renderValidatedComponentWithoutOwnerOrContext (app.js:43196)
at ReactCompositeComponentWrapper._renderValidatedComponent (app.js:43223)
at ReactCompositeComponentWrapper._updateRenderedComponent (app.js:43147)
at ReactCompositeComponentWrapper._performComponentUpdate (app.js:43125)
at ReactCompositeComponentWrapper.updateComponent (app.js:43046)
at ReactCompositeComponentWrapper.receiveComponent (app.js:42948)
at Object.receiveComponent (app.js:35341)
更新2:
所以检查一下。我的{ObjectID}做错了。我拉了一个用户并从数据库中引用了一个&#39; _id&#39;但没有&#39; id&#39;对象上的属性。这是输出:
> db.users.find({})
{ "_id" : ObjectId("586253169465191cb812066c"), "name" : "me", "id" : ObjectId("586253169465191cb812066c"), "errors" : [ ] }
> db.quotes.find({})
{ "_id" : ObjectId("586693333ff93f3581c0ca05"), "text" : "Hi Prisc", "author" : "H. Jackson Brown", "likesCount" : 24 }
{ "_id" : ObjectId("586693333ff93f3581c0ca06"), "text" : "If opportunity doesn't knock, build a door", "author" : "Milton Berle", "likesCount" : 2 }
{ "_id" : ObjectId("586693333ff93f3581c0ca07"), "text" : "Try to be a rainbow in...", "author" : "Maya Angelou" }
如果我从globalIdFetcher()中记录id,那么Jackson Brown Quote对象的记录ID会按预期显示两个id,但它们都与db中的id相同且不同。控制台中的输出是:
{
"viewer": {
"__dataID__": "VXNlcjo=",
"quotes": {
"__dataID__": "client:6068631311_first(100),searchTerm()",
"edges": [
{
"__dataID__": "client:client:6068631311:UXVvdGU6NTg2NjkzMzMzZmY5M2YzNTgxYzBjYTA1",
"node": {
"__dataID__": "UXVvdGU6NTg2NjkzMzMzZmY5M2YzNTgxYzBjYTA1",
"id": "UXVvdGU6NTg2NjkzMzMzZmY5M2YzNTgxYzBjYTA1",
"__fragments__": {
"1::client": [
{
"showLikes": false
}
]
}
}
},
有关修复此语法的任何想法吗?
答案 0 :(得分:0)
使用所提供的信息解决问题非常困难。当您请求指导时,这是我的建议:)
我无法理解为什么它第一次填充搜索字段而不是在搜索表单中输入。
因为Relay获取searchTerm
的初始值的结果,在您的情况下这是一个空字符串。您必须在服务器端处理此情况(通过检查输入searchTerm
)和客户端(例如,通过检查searchTerm
的当前值是否为空)。
当您输入搜索表单时,系统不会调用search()
,也不会更新searchTerm
。检查SearchForm
组件。
当我使用搜索表单时,我在浏览器中收到错误“app.js:8284 Uncaught TypeError:无法读取未定义的属性'edge'。
开始调试服务器端为quotes
GraphQL对象类型下的viewer
字段返回的内容。模式中db.collection('quotes').find(findParams).toArray()
的输出是什么?另外,在console.log(JSON.stringify(this.props, null, 4))
类的render()
函数中添加App
。检查你看到了什么。您还可以在Chrome DevTools网络选项卡上检查HTTP请求和响应。按graphql
过滤。
答案 1 :(得分:0)
解决方案是将Quote类型从nodeInterface中取出,这样只通过nodeInterface运行顶级对象,让relay从GraphQLID或fromGlobalId生成objectId的id,如各个itemType中所定义。