[experimental] How to share data between pages where the fragment reference can't be explicitly passed?
- Dominant language
- Rust
- Stars
- 19k
- Forks
- 1.9k
- PR merge metrics
- No merged PRs in 30d
Description
## Lib version
`"react-relay": "0.0.0-experimental-183bdd28",`
## Problem
Page1 will fetch a list of projects, which is a relay connection
```typescript
const pageQuery = graphql`
query ProjectList_PageQuery($orgId: String!) {
...ProjectList_FragmentQuery @arguments(orgId: $orgId)
}
`
const connectionQuery = graphql`
fragment ProjectList_FragmentQuery on Query
@argumentDefinitions(
orgId: { type: "String!" }
first: { type: "Int", defaultValue: 50 }
after: { type: "String" }
last: { type: "Int" }
before: { type: "String" }
)
@refetchable(queryName: "ProjectListPaginationQuery") {
projectConnection(orgId: $orgId, first: $first, after: $after)
@connection(key: "ProjectList_projectConnection") {
edges {
node {
id
...ProjectListItem_project
}
}
}
}
`
```
Click the item of the list will go to page 2 with a project id
Page2 will display the project
### Two problems here:
1. How to reuse the data which has been fetched from Page1 for this very project on Page 2, for example the data defined in fragment `ProjectListItem_project`?
1. How to re-fetch the query so I can update both the project list and the project?
The current `useFragment` need me to pass a ref from the parent query, the problem here is: The `` page is not a children of `` page, there is a re-routing happening at the frontend.
## Workaround?
I am currently use `commitLocalUpdate` to **read** value from the store
```typescript
const [projectName, setProjectName] = React.useState('')
React.useEffect(() => {
if (!id) return
commitLocalUpdate(relayEnv, (store) => {
const projectConnection = ConnectionHandler.getConnection(
store.getRoot(),
'ProjectList_projectConnection',
)
if (!projectConnection) {
// user refreshed the page so no cache
// let's start a new request
} else {
const edges = projectConnection.getLinkedRecords('edges')
const projectEdge = edges.find((edge) => edge.getLinkedRecord('node').getDataID() === id)
const projectRecord = projectEdge.getLinkedRecord('node')
const projectName = projectRecord.getValue('name')
setProjectName(projectName)
}
})
}, [])
// use projectName to render, it is from the cache
```
I do not know if it is not ideal, since that's a lot of code...
I started to save the data to Redux to make it a lot simpler, but feel redundant since it is already in the Relay store.
a side question:
3. it happens for the `useQueryLoader` and `usePreloadedQuery`, where `usePreloadedQuery` need the queryRef from `useQueryLoader`, but when I switch between pages, I want to fetch the data needed for route 2 before leaving route 1, and I can not figure out how to do it, like construct the ref object with a new API?
### What is the Relay idiomatic way to solve these 3 problems? Thanks :)
Contributor guide
Assessment
This issue has not been assessed yet.