简体   繁体   English

在QueryRenderer中传递中继现代变量

[英]Passing relay modern variable in QueryRenderer

I'm using relay-modern. 我正在使用现代继电器。 The following is getting me an error saying that $limit is not defined. 以下是使我出错的错误,即未定义$ limit。 How would I define the limit in the QueryRenderer? 如何在QueryRenderer中定义限制? My thinking is that the limit was defined in Main.js but it looks like I need to somehow reference it in the QueryRenderer. 我的想法是该限制是在Main.js中定义的,但是看起来我需要以某种方式在QueryRenderer中引用它。 I have a QueryRenderer in my app.js file that calls a fragment on another component, Main.js. 我的app.js文件中有一个QueryRenderer,它调用另一个组件Main.js上的片段。 app.js looks like this, Main.js follows: app.js看起来像这样,Main.js如下:

```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')
)

``` ```

The ...Main_store fragment being called there is coming from this component, Main.js ... Main_store片段在那里被调用来自这个组件Main.js

```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

``` ```

This is the error in Chrome DevTools Network Tab on the query. 这是查询中“ 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
                }
            ]
        }
    ]
}

Any ideas would be greatly appreciated.(This mostly generated using the Relay Conversion Playbook ) Thank you. 任何想法都将不胜感激。(这主要是使用“ 中继转换手册”生成的)谢谢。

Updating - Adding schema in case that helps get answer: 更新-添加架构以防出现答案:

``` ```

type Business implements Node { # The ID of an object id: ID! 类型Business实现节点{#对象ID的ID:ID! name: String url: String state: String likesCount: Int createdAt: String } 名称:字符串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
}

``` ```

QueryRenderer can take a variables prop. QueryRenderer可以使用variables prop。 Try this: 尝试这个:

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

Now you can reference $limit in any fragment children of the QueryRenderer query. 现在,您可以在QueryRenderer查询的任何片段子级中引用$limit

If you need to change the value of $limit and refetch, use createRefetchContainer and call the refetch method. 如果您需要更改$limit和refetch的值,请使用createRefetchContainer并调用refetch方法。

This GitHub comment addresses the issue, and will be incorporated into the Relay Modern documentation. GitHub上的注释解决了该问题,并将其合并到Relay Modern文档中。

Example available here 此处提供示例

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM