Hey! I’m getting my head around the Cells and had to deal with a use case where I’m not really content with the solution. Here it is:
I have a classical example of a master-detail view - a grid displaying users and a form for editing a single user. The grid and the form are sibling components wrapped into cells. The cells fetch data for the corresponding components - list of users for the grid and required data for the form (available roles, departments, etc.).
Once the form is successfully submitted I need to refresh data in the grid. But since I cannot pass props directly through the cell components (at least I couldn’t find how to do this) I had to find a way to communicate this event indirectly.
I ended up adding two contexts:
one for communication between the form and the parent component that hosts both - the form and the grid.
second for communication between the parent and the grid components.
(Both of these components can be used on other pages, I didn’t want to couple them to this particular page, so instead of one shared context I had to introduce two.)
Everything is working fine, but the solution seems an overkill and I feel that I must be missing something obvious. I would really appreciate, If anyone can suggest any alternative approach or provide an opinion on this one. Thank you!
I’m assuming you’re using the Cell for the data-fetching part of the equation, and then making use of useMutation to actually update the data, once the form is submitted.
The useMutation hook has a second argument, an options object, which accepts a refetchQueries field. If you want to pass props to the grid-cell, which are the same as passing variables to its GraphQL query, you can do so through refetchQueries by passing it an object - instead of a DocumentNode or the name of the query (see linked docs).
// I believe @redwoodjs/web also exports this hook - I just always use Apollo's.
// Better types :)
import { useMutate } from '@apollo/client'
import { QUERY } from 'src/components/MyCell'
export const MyForm = () => {
const [mutation, ...] = useMutation(MUTATION, {
refetchQueries: [{ query: QUERY, variables: { ...cell_props } }]
})
}
As for getting which user you want to update, I typically delegate that responsibility to the Page component. My most recent pattern was passing the cell the results of a useState hook, and then giving the form-component the current value. The cell can then update the state, using the setter, whenever the edit button is clicked - for example.
Hopefully this is up the alley you were expecting!
Indeed, I was using refetch (injected into the Success cell component though), but I didn’t know that Cell variables also carry the Cell props and not only the query variables. Another thing that was not obvious to me - how to make it work with TypeScript. Here is what I ended up doing, though eventually I don’t even need to use Cell variables: