Pass variables to fragment container in relay mode

2019-02-06 17:58发布

I'm using Relay Modern (compat). I have a fragment that contains a field that has one argument, but I can't find a way of passing the variable value from the parent component:

// MyFragmentComponent.jsx

class MyFragmentComponent extends Component {...}

const fragments = {
  employee: graphql`
    fragment MyFragmentComponent_employee on Employee {
      hoursWorked(includeOvertime: $includeOvertime)
      dob
      fullName
      id
    }
  `,
}

export default Relay.createFragmentContainer(MyFragmentComponent, fragments)

It will end up saying $includeOvertime is not defined. The context where this component is being rendered looks like this:

// MyRootComponent.jsx

class MyRootComponent extends Component {
  render() {
    const { employee } = this.props
    const includeOvertime = //... value is available here

    return (
      <div>
        <MyFragmentComponent employee={employee} />
      </div>
    )
  }
}

const query = graphql`
  query MyRootComponentQuery($employeeId: String!) {
    employee(id: $employeeId) {
      fullName
      ...MyFragmentComponent_employee
    }
  }
`

export default MyUtils.createQueryRenderer(MyRootComponent, query) // this just returns a QueryRenderer

With relay classic you would pass variables this way:

....
employee(id: $employeeId) {
  fullName
  ${MyFragmentComponent.getFragment('employee', variables)}
}

How can I achieve the same with relay modern?

1条回答
闹够了就滚
2楼-- · 2019-02-06 18:35

Using @argumentDefinitions and @arguments directives seems to be the way to go. In relay versions before 1.4.0 graphql.experimental had to be used instead of graphql.

In the fragment definition:

const fragments = {
  employee: graphql`
    fragment MyFragmentComponent_employee on Employee
    @argumentDefinitions(includeOvertime: { type: "Boolean", defaultValue: false }) {
      hoursWorked(includeOvertime: $includeOvertime)
      dob
      fullName
      id
    }
  `,
}

If you want the argument to be required:

@argumentDefinitions(includeOvertime: { type: "Boolean!" })

In the parent component you should specify the arguments for the fragment like this:

const query = graphql`
  query MyRootComponentQuery($employeeId: String!, $includeOvertime: Boolean) {
    employee(id: $employeeId) {
      fullName
      ...MyFragmentComponent_employee @arguments(includeOvertime: $includeOvertime)
    }
  }
`

In this page in the official relay docs there is an example of directives for defining/passing arguments.

UPDATE:

Since relay version 1.4.0 graphql.experimental was deprecated and now all the features are supported by the regular graphql tag.

UPDATE:

In relay version 1.5.0 graphql.experimental was removed.

查看更多
登录 后发表回答