2017-05-15 4 views
1

나는 relay-modern를 사용하고 있습니다. 다음은 $ limit가 정의되어 있지 않다는 오류 메시지입니다. QueryRenderer에서 한계를 정의하는 방법은 무엇입니까? 내 생각에 한계가 Main.js에 정의되어 있지만 QueryRenderer에서 어떻게 든 참조해야하는 것처럼 보입니다. 내 app.js 파일에 다른 컴포넌트 인 Main.js의 프래그먼트를 호출하는 QueryRenderer가있다. app.js는 다음과 같습니다, Main.js은 다음과 같습니다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') 
) 

```

그 ...이 구성 요소 홈페이지에서가오고 호출되는 Main_store 조각 된 .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 Network Tab의 쿼리 오류입니다.

{ 
    "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 :

```

종류 비즈니스는 노드 { # 객체 ID의 ID를 구현! 이름 : 문자열 URL : 문자열 상태 : 문자열 likesCount : 지능 createdAt : 문자열 은}

# 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 
} 

```

답변

4

QueryRenderer는 variables 소품이 걸릴 수 있습니다. 이 시도 :

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

는 이제 QueryRenderer 쿼리의 조각 어린이 $limit를 참조 할 수 있습니다.

$limit 값을 변경하고 다시 가져와야하는 경우 createRefetchContainer을 사용하고 refetch 메서드를 호출하십시오.

This GitHub comment은이 문제를 해결하고 Relay Modern 문서에 통합됩니다.

예 사용 가능 here

+0

"createRefetchContainer 사용"이란 무엇을 의미합니까? 추가 구성 요소를 만들어 RefetchContainer에 래핑하는 것을 의미합니까? RefetchContainer를 사용하여 변수를 수정하고 refetch를 호출하여 루트 쿼리를 다시 실행하는 방법을 잘 모르겠습니다. – bjlevine

+0

@bjlevine 페이스 북의 문서는 이것으로 문제가 없다고 생각합니다. refetch를 실행하고 쿼리 변수를 변경하는 방법의 예제가 있습니다. 그런 다음 refetchContainer가 QueryRenderer (또는 해당 하위)에서 렌더링됩니다. https://facebook.github.io/relay/docs/refetch-container.html –