Relay: [Modern] createRefetchContainer doesn't fill props

Created on 27 Apr 2017  路  14Comments  路  Source: facebook/relay

Hi folks! I'm trying to create a component to handle with my data stuff(passing queries and fragments through props), but I couldn't make it work and neither find examples with the best way to do that.

Here's my DataTable component: _(not finished yet)_

class DataTable extends Component {
  constructor (props) {
    super(props)

    this.state = {
      first: props.first,
      count: props.first
    }
  }

  _loadMore () {
    const variables = {
      first: this.state.first + this.state.count
    }

    this.setState(variables)

    this.props.relay.refetch(variables)
  }

  render () {
    console.log(this.props)

    return (
      <div>
        <a onClick={() => this._loadMore()}>More</a>
      </div>
    )
  }
}

const DataTableQueryRenderer = (props) => {
  const DataTableRefetchContainer = createRefetchContainer(
    DataTable,
    props.fragments,
    props.query
  )

  return (
    <QueryRenderer
      environment={props.environment}
      query={props.query}
      variables={props.variables}
      render={() => {
        return (
          <DataTableRefetchContainer
            {...props.variables}
          />
        )
      }}
    />
  )
}

export default DataTableQueryRenderer

This is how I use it:

<DataTable
  environment={RelayEnvironment}
  query={graphql`
    query users_list_Query($first: Int!, $search: String) {
      viewer {
        ...users_list_users
      }
    }
  `}
  fragments={{
    users: graphql`
      fragment users_list_users on Viewer {
        users(first: $first, search: $search) {
          edges {
            node {
              name
              email
            }
          }
        }
      }
    `
  }}
  variables={{
    first: 3,
    search: ''
  }}
/>

But the console.log on render() method always returns users as null. Any ideas?

Thanks!

Most helpful comment

i've tried a lot of things, nothing worked... i'm feeling stuck right now

All 14 comments

same here, this was suppose to be fixed in version rc.3 but the problem still persists.

i've tried a lot of things, nothing worked... i'm feeling stuck right now

what version of react-relay are u using?

v1.0.0-rc.3

Do you think this is the same as #1695? It seems like it might be

I think it might be! My queries are executed normally too, but the users prop keep comming null.

Initially:

1-request

Console output:

1-console

After click on _more_:

2-request

Console output:

2-console

Anything I could do to help? I'm new here.

Thanks!

Using PaginationContainer currently requires two additional steps:

I suspect you might have the directive but be missing the connection provider.

Hey @josephsavona, thanks for the reply. I'm actually using RefetchContainer instead of PaginationContainer. Anyway, tried to add the handlerProvider on my Environment and added @connection(key: "users_list_users") to my query... Unfortunately the problem still occurs.

@felippepuhle first, how you bypassing relay compiler using props.fragments? because Im trying your example code but relay-compiler give me.
Error: FindGraphQLTags:createRefetchContainerexpects a second argument of fragment definitions.
But somehow i can bypass it.

Second. I think you should passing viewer props on QueryRenderer props. then you should return loading component or return null in render props. like this :

const DataTableQueryRenderer = (propsx: any) => {
  const DataTableRefetchContainer = createRefetchContainer(
    DataTable,
    propsx.fragments,
    propsx.query
  )

  return (
    <QueryRenderer
      environment={propsx.environment}
      query={propsx.query}
      variables={propsx.variables}
      render={({ props }) => {
        if (props) {
          return <DataTableRefetchContainer {...propsx.variables} viewer={props.viewer} />

        }
        return <div>loading</div> // or return null
      }}
    />
  )
}

Hey @nosykretts! This is how I pass query and fragments through my component:

<DataTable
  environment={RelayEnvironment}
  fragments={{
    users: graphql`
      fragment users_list_users on Viewer {
        users(first: $first, search: $search) {
          edges {
            node {
              id
              name
              email
            }
          }
          pageInfo {
            hasNextPage
          }
        }
      }
    `
  }}
  query={graphql`
    query users_list_Query($first: Int!, $search: String) {
      viewer {
        ...users_list_users
      }
    }
  `}
  variables={{
    first: 3,
    search: ''
  }}
/>

Already tried to pass viewer to the container too, but somehow it's an empty object:

viewer

Already made the loading component too.

Any idea?

I think you need to change your code like this :

<DataTable
  environment={RelayEnvironment}
  fragments={{
    viewer: graphql` //this line
      fragment users_list_viewer on Viewer { //this line
        users(first: $first, search: $search) {
          edges {
            node {
              id
              name
              email
            }
          }
          pageInfo {
            hasNextPage
          }
        }
      }
    `
  }}
  query={graphql`
    query users_list_Query($first: Int!, $search: String) {
      viewer {
        ...users_list_viewer //this line
      }
    }
  `}
  variables={{
    first: 3,
    search: ''
  }}
/>

and dont forget to re-run relay-compiler after code change.

Hey @nosykretts, it worked! Thanks for your help, I'm really thankful.

I thought I'd tried it that way... guess I was wrong.

Thanks again!

@nosykretts how did you "But somehow i can bypass it." ?

@chollier you have to exclude DataTable.js from relay-build because DataTable.js is a generic container.
Check https://github.com/facebook/relay/blob/master/packages/relay-compiler/bin/RelayCompilerBin.js#L40-L42

Was this page helpful?
0 / 5 - 0 ratings

Related issues

luongthanhlam picture luongthanhlam  路  3Comments

jstejada picture jstejada  路  3Comments

johntran picture johntran  路  3Comments

derekdowling picture derekdowling  路  3Comments

amccloud picture amccloud  路  3Comments