2017-05-15 1 views
1

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 
} 

`` `

Antwort

4

QueryRenderer kann eine variables prop nehmen. Versuchen Sie folgendes:

<QueryRenderer 
    // ... 
    variables={{ 
    limit: 10, 
    }} 
    // ... 
/> 

Jetzt Sie $limit in jedem Fragment Kinder der QueryRenderer Abfrage verweisen können.

Wenn Sie den Wert $limit ändern und neu holen müssen, verwenden Sie createRefetchContainer und rufen Sie die Methode refetch auf.

This GitHub comment behebt das Problem und wird in die Dokumentation Relay Modern aufgenommen.

Beispiel verfügbar here

+0

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

+0

@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 –

Verwandte Themen