在 QueryRenderer 中传递中继现代变量
Posted
技术标签:
【中文标题】在 QueryRenderer 中传递中继现代变量【英文标题】:Passing relay modern variable in QueryRenderer 【发布时间】:2017-10-14 07:56:13 【问题描述】:我正在使用现代继电器。以下是给我一个错误,说 $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 生成的)谢谢。
更新 - 添加模式以帮助获得答案:
```
类型业务实现节点 # 对象的ID 身份证:身份证! 名称:字符串 网址:字符串 状态:字符串 喜欢计数:整数 创建时间:字符串
# 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
```
【问题讨论】:
【参考方案1】:QueryRenderer 可以采用 variables
属性。试试这个:
<QueryRenderer
// ...
variables=
limit: 10,
// ...
/>
现在您可以在 QueryRenderer
查询的任何片段子项中引用 $limit
。
如果您需要更改$limit
的值并重新获取,请使用createRefetchContainer
并调用refetch
方法。
This GitHub comment 解决了这个问题,并将被纳入 Relay Modern 文档中。
示例可用here
【讨论】:
“使用 createRefetchContainer”是什么意思?您的意思是创建一个附加组件并将其包装在 RefetchContainer 中吗?我不确定您将如何使用 RefetchContainer 来修改变量并调用 refetch 以重新执行根查询。 @bjlevine 我认为 Facebook 文档对此很好 - 有一个如何执行重新获取和更改查询变量的示例。然后,您的 refetchContainer 将在 QueryRenderer(或适当的子级)下呈现。 facebook.github.io/relay/docs/refetch-container.html以上是关于在 QueryRenderer 中传递中继现代变量的主要内容,如果未能解决你的问题,请参考以下文章
如何将自定义道具传递给 QueryRenderer 渲染函数?