Describe the bug
Hi folks! Big fan of Urql here. In the update to 1.6.0, interaction between useQuery and the React Context API stopped working in the same way. Here's the relevant code (pulled out from my own project, codesandbox link below):
// viewer-context.tsx
export const ViewerContext = createContext<ViewerContextValue>({
fetching: true,
viewer: null
})
export function ViewerProvider({ children }: { children: ReactNode }) {
const [res] = useQuery<{ viewer: User | null }>({
query: viewerQuery
})
const value = {
fetching: res.fetching,
viewer: res.data && res.data.viewer ? res.data.viewer : null
}
return (
<ViewerContext.Provider value={value}>{children}</ViewerContext.Provider>
)
}
// Main.tsx, which consumes that context using `useContext`
export default function Main() {
const { viewer, fetching } = useContext(ViewerContext)
console.log(fetching)
// Still loading
if (fetching) return null
return <h1>Hi!</h1>
}
I'm able to reliably reproduce differing behavior between 1.5.1 and 1.6.0. In the former, when res.fetching changes, consumers of the context are updated (the console.log in Main.tsx follows the updates). That is not the behavior I'm seeing in 1.6.0 - the Context API checks for object equality using Object.is, so I'm guessing something has changed there (presumably in #447)? That doesn't really make sense, but updating urql is the only change I've made while testing this out.
In setting up the below codesandbox, I've realized that maybe using a Context for not repeating the same query is unnecessary thanks to urql's caching - I'd love your opinion there, but either way I'm bringing this up as a likely unintentional regression in 1.6.0!
Steps to reproduce
A codesandbox link (thanks for the template below!): https://codesandbox.io/embed/urql-issue-template-client-vj73c
Expected behavior
I'd expect consumers of a Context that sets a value using res.fetching to correctly update consumers of the context.
Actual behavior
The value is updated in the provider itself, but not in the consumers. You can toggle between 1.5.1 and 1.6.0 in the Codesandbox link to see it in action!
Thanks! Let me know how I can help ❤️
This is indeed very odd! 🤔
I’ve checked the CodeSandbox and the parent component with useQuery seems to be updating reliably — after a while I’m seeing res.fetching === true there.
But this update somehow doesn’t trigger a context change, although a new context value is created on every render. Instead the change seems to be swallowed and the child never receives the update.
Ok, I was able to reproduce this on react-wonka in isolation, so I should be able to figure out how to fix this. This kind of seems like a weird edge-case, since the component with useStreamValue (in the case of urql, useQuery) does update correctly. https://github.com/kitten/react-wonka/pull/1
Edit: okay, I found the issue, although I'm not sure what React specifically is doing here. I'm just glad that it'll be fixed 😆
@kitten can we get new patch release, i have similar problem
The hotfix has been merged and 1.6.1 has been published. Also verified that it's fixed here: https://codesandbox.io/s/urql-issue-template-client-6sbwx
@JasonEtco Nice catch! :tada: And thanks for reporting it this promptly with such a nice reproduction 🙏
Amazing, that was so fast! ⚡️⚡️⚡️ Thank you for the quick fix @kitten ❤️ I've confirmed that 1.6.1 works as expected in my project!
@kitten thanks for the quick fix, working great now ^^