facebook / facebook/relay

Relay classic to relay modern migration

Open
#4,253 5 comments 0 reactions 0 assignees View on GitHub
Dominant language
Rust
Stars
19k
Forks
1.9k
PR merge metrics
No merged PRs in 30d

Description

Hey, I'm working on migrating super-duper old project made in relay which apparently has no documentation (0.9.4).
Since project is made with class components, I made the decision to move to relay modern without hooks (legacy API).
I saw a migration guide, but not everything is clear to me.

here's an example how it is currently working, React-router (v3) route:
```

```

ViewerQueries
```
const ViewerQueries = {
viewer: () => Relay.QL`query { viewer }`,
}
```

Login Component
```
export class _Login extends React.Component {
render() {
return // 3.
}
}

export default Relay.createContainer(_Login, {
fragments: {
viewer: () => Relay.QL`
fragment on Viewer {
${LoginPageContent.getFragment('viewer')},
}
`,
},
})
```

LoginPageContent
```
export default Relay.createContainer(Login, {
initialVariables: {},

fragments: {
viewer: () => Relay.QL`
fragment on Viewer {
user {
id
username
userProfile {
showTermsOfServiceModal
isAmbassador
isInternal
isLite
isExternal
}
}
${TermsOfServiceModal.getFragment('viewer')}
${AuthMutation.getFragment('viewer')},
}
`,
},
})
```
How do I put ${SomeComponent.getFragment('someFragment') in relay modern? Currently it says it came across dollar sign and won't process.

What I've done:
- I moved everything from LoginPageContent component to Login component
- At first I tried to mimic fragment, but it wouldn't work saying that's not enclosed in QueryRenderer
```
export const createFragmentContainer(_Login, {
viewer: graphql`
fragment Login on Viewer {
user {
id
username
userProfile {
showTermsOfServiceModal
isAmbassador
isInternal
isLite
isExternal
}
}
}
`,
});
```
- the QueryRenderer worked, but I don't know if moving from fragments to whole queries is the right way:
```
const Login = () => {
const router = useRouter();

return (
(
<_Login
{...props}
router={router}
/>
)}
/>
);
};
```
- Mutation (before):
```
export default class AuthMutation extends Relay.Mutation {
static fragments = {
viewer: () => Relay.QL`
fragment on Viewer {
id
}
`,
}

getMutation = () => {
if (this.props.login) {
return Relay.QL`mutation {logIn}`
} else {
return Relay.QL`mutation {logOut}`
}
}

getVariables = () => {
const { login, params } = this.props
if (login) {
return params
}
}

getFatQuery = () => {
if (this.props.login) {
return Relay.QL`
fragment on LogInMutationPayload {
viewer
}
`
} else {
return Relay.QL`
fragment on LogOutMutationPayload {
viewer {
user
}
}
`
}
}

getConfigs = () => [
{
type: 'FIELDS_CHANGE',
fieldIDs: {
viewer: this.props.viewer.id,
},
},
]
}
```
- Same mutation modified to be compatible with relay-modern. Is this ok?
```
export const authMutation = (environment, variables) => {
const getMutation = () => {
if (variables) {
return graphql`mutation newAuthMutationLoginMutation($input: LogInMutationInput!) {
logIn(input: $input) {
clientMutationId
viewer {
user {
email
}
}
}
}`;
}

return graphql`mutation newAuthMutationLogoutMutation($input: LogOutMutationInput!) {
logOut(input: $input) {
clientMutationId
viewer {
user {
email
}
}
}
}`;
};
const getVariables = () => {
const {
login,
name,
password,
} = variables;

if (login) {
return {
name,
password,
};
}

return {};
};

const getConfigs = () => [
{
fieldIDs: {
viewer: variables.viewer.id,
},
type: 'FIELDS_CHANGE',
},
];

return commitMutation(environment, {
configs: getConfigs(),
mutation: getMutation(),
onCompleted: res => variables.onSuccess(res), // this is on purpose, since where those mutations are triggered they have onSucces and onError keys
onError: tx => variables.onFailure(tx),
variables: {
input: getVariables(),
},
});
};
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.