我正在使用接力现代。以下是给我一个错误,说没有定义$ limit。如何在QueryRenderer中定义限制? 我的想法是限制是在Main.js中定义的,但看起来我需要以某种方式在QueryRenderer中引用它。我的app.js文件中有一个QueryRenderer,它调用另一个组件Main.js上的片段。 app.js看起来像这样,Main.js如下:
```的js
import '../style/style.css'
import React from 'react'
import ReactDOM from 'react-dom'
import { QueryRenderer, graphql } from 'react-relay'
import environment from './createRelayEnvironment'
import Main from './components/Main'
// change rootContainer to QueryRenderer
ReactDOM.render(
<QueryRenderer
environment={environment}
query={graphql`
query appQuery {
store {
...Main_store
}
}
`}
// variables={{limit: 100, query: ''}}
render={({ error, props}) => {
if (props) {
return <Main store={props.store} />
} else {
return <div>Loading</div>
}
}}
/>,
document.getElementById('react')
)
```
在那里调用的Main_store片段来自这个组件Main.js
```的js
import React from 'react'
import {
createFragmentContainer,
createRefetchContainer,
graphql
} from 'react-relay'
import { debounce } from 'lodash'
import Business from './Business'
import CreateBusinessMutation from '../mutations/CreateBusinessMutation'
class Main extends React.Component {
constructor (props) {
super(props)
// TODO props.relay.* APIs do not exist on compat containers
// TODO needs manual handling
this._loadMore = debounce(this._loadMore, 300)
this.props.relay.Variables = { limit: 100, query: '' }
}
search = (e) => {
// TODO needs manual handling
this._loadMore({ query: e.target.value })
};
setLimit = (e) => {
// TODO needs manual handling
this._loadMore({ limit: Number(e.target.value) })
};
handleSubmit = (e) => {
e.preventDefault()
let onSuccess = () => {
$('#modal').closeModal()
}
let onFailure = (transaction) => {
const error = transaction.getError() || new Error('Mutation failed.')
console.error(error)
}
let name = this.refs.newName.value = ''
let url = this.refs.newUrl.value = ''
CreateBusinessMutation.commit(
this.props.relay.environment,
name,
url,
this.props.store
),
{onFailure, onSuccess}
}
componentDidMount () {
$('.modal-trigger').leanModal()
}
render () {
let content = this.props.store.businessConnection.edges.map(edge => {
return <Business key={edge.node.id} business={edge.node} />
})
return (
<div>
<div className="input-field">
<input id="search" type="text" onChange={this.search} />
<label htmlFor="search">Search All Businesses</label>
</div>
<div className="row">
<a className="waves-effect waves-light btn modal-trigger right light-blue white-text" href="#modal">Add New Business</a>
</div>
<ul>
{content}
</ul>
<div className="row">
<div className="col m3 hide-on-small-only">
<div className="input-field">
<select id="showing" className="browser-default"
// TODO props.relay.* APIs do not exist on compat containers
onChange={this.setLimit} defaultValue={this.props.relay.variables.limit}>
<option value="100">Show 100</option>
<option value="200">Show 200</option>
</select>
</div>
</div>
</div>
<div id="modal" className="modal modal-fixed-footer">
<form onSubmit={this.handleSubmit}>
<div className="modal-content">
<h5>Add New Business</h5>
<div className="input-field">
<input type="text" id="newName" ref="newName" required className="validate" />
<label htmlFor="newName">Name</label>
</div>
<div className="input-field">
<input type="url" id="newUrl" ref="newUrl" required className="validate" />
<label htmlFor="newUrl">Url</label>
</div>
</div>
<div className="modal-footer">
<button type="submit" className="waves-effect waves-green btn-flat green darken-3 white-text">
<strong>Add</strong>
</button>
<a href="#!" className="modal-action modal-close waves-effect waves-red btn-flat">Cancel</a>
</div>
</form>
</div>
</div>
)
}
_loadMore () {
// Increments the number of stories being rendered by 10.
const refetchVariables = fragmentVariables => ({
query: fragmentVariables.query,
limit: fragmentVariables.limit
})
this.props.relay.refetch(refetchVariables, null);
}
}
Main = createRefetchContainer(Main, {
/* TODO manually deal with:
initialVariables: {
limit: 100,
query: ''
}
*/
store: graphql`
fragment Main_store on Store {
id,
businessConnection(first: $limit, query: $query) {
edges {
node {
id,
...Business_business
}
}
}
}
`
},
graphql`
query MainRefetchQuery($limit: Int, $query: String) {
store {
...Main_store
}
}
`,
)
export default Main
```
这是查询中Chrome DevTools网络标签中的错误。
{
"errors": [
{
"message": "Variable \"$limit\" is not defined by operation \"appQuery\".",
"locations": [
{
"line": 10,
"column": 29
},
{
"line": 1,
"column": 1
}
]
},
{
"message": "Variable \"$query\" is not defined by operation \"appQuery\".",
"locations": [
{
"line": 10,
"column": 44
},
{
"line": 1,
"column": 1
}
]
},
{
"message": "Variable \"$showLikes\" is not defined by operation \"appQuery\".",
"locations": [
{
"line": 24,
"column": 27
},
{
"line": 1,
"column": 1
}
]
}
]
}
非常感谢任何想法。(这主要是使用Relay Conversion Playbook生成的)谢谢。
更新 - 在有助于获得答案的情况下添加架构:
```
类型Business实现Node { #对象的ID id:ID! name:String url:字符串 state:String likesCount:Int createdAt:String }
# A connection to a list of items.
type BusinessConnection {
# Information to aid in pagination.
pageInfo: PageInfo!
# A list of edges.
edges: [BusinessEdge]
}
# An edge in a connection.
type BusinessEdge {
# The item at the end of the edge
node: Business
# A cursor for use in pagination
cursor: String!
}
input CreateBusinessInput {
name: String!
url: String!
clientMutationId: String
}
type CreateBusinessPayload {
businessEdge: BusinessEdge
store: Store
clientMutationId: String
}
type Mutation {
createBusiness(input: CreateBusinessInput!): CreateBusinessPayload
thumbsUp(input: ThumbsUpInput!): ThumbsUpPayload
}
# An object with an ID
interface Node {
# The id of the object.
id: ID!
}
# Information about pagination in a connection.
type PageInfo {
# When paginating forwards, are there more items?
hasNextPage: Boolean!
# When paginating backwards, are there more items?
hasPreviousPage: Boolean!
# When paginating backwards, the cursor to continue.
startCursor: String
# When paginating forwards, the cursor to continue.
endCursor: String
}
type Query {
# Fetches an object given its ID
node(
# The ID of an object
id: ID!
): Node
store: Store
}
type Store implements Node {
# The ID of an object
id: ID!
businessConnection(after: String, first: Int, before: String, last: Int, query: String): BusinessConnection
}
input ThumbsUpInput {
businessId: String
clientMutationId: String
}
type ThumbsUpPayload {
business: Business
clientMutationId: String
}
```
答案 0 :(得分:4)
QueryRenderer可以使用return StreamSupport.stream( Spliterators.spliteratorUnknownSize( new Iterator<Node>()
{
@Override
public boolean hasNext()
{
// to implement
return ...;
}
@Override
public ContentVersion next()
{
// to implement
return ...;
}
}, 0 ), false );
道具。试试这个:
variables
现在,您可以在<QueryRenderer
// ...
variables={{
limit: 10,
}}
// ...
/>
查询的任何片段子代中引用$limit
。
如果您需要更改QueryRenderer
的值并重新提取,请使用$limit
并调用createRefetchContainer
方法。
This GitHub comment解决了这个问题,并将其纳入Relay Modern文档中。
可用示例here