Ich benutze Relais-modern. Das folgende bringt mir einen Fehler, der besagt, dass $ limit nicht definiert ist. Wie würde ich das Limit im QueryRenderer definieren? Mein Gedanke ist, dass das Limit in Main.js definiert wurde, aber es sieht so aus, als müsste ich es irgendwie im QueryRenderer referenzieren. Ich habe einen QueryRenderer in meiner app.js-Datei, die ein Fragment in einer anderen Komponente, Main.js, aufruft. app.js wie folgt aussieht, main.js folgt:Weitergabe der modernen Variable in QueryRenderer
`` `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')
)
` ``
Das ... Main_store Fragment dort genannt wird, wird von dieser Komponente kommt, 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
` ``
Dies ist der Fehler in der Chrome DevTools-Registerkarte "Netzwerk" in der Abfrage.
{
"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
}
]
}
]
}
Irgendwelche Ideen würde sehr geschätzt werden. (Diese meist erzeugt mit der Relay Conversion Playbook) Danke.
Updating - Schema im Fall Hinzufügen die Antwort hilft erhalten: Geschäfts
`` `
Typ implementiert Knoten { # Die ID eines Objekts ID: ID! name: String url: String 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
}
`` `
Was meinst du mit "createRefetchContainer verwenden?" Meinst du eine zusätzliche Komponente erstellen und sie in einen RefetchContainer einbinden? Ich bin nicht wirklich sicher, wie Sie einen RefetchContainer verwenden würden, um die Variable zu ändern, und rufen Sie erneut ab, um die Stammabfrage erneut auszuführen. – bjlevine
@bjlevine Ich denke, die Facebook-Dokumente sind in Ordnung - es gibt ein Beispiel, wie ein Refetch ausgeführt und die Abfragevariablen geändert werden. Ihr refetchContainer wird dann unter QueryRenderer (oder dem entsprechenden Kind) gerendert. https://facebook.github.io/relay/docs/refetch-container.html –