Lightwaves
Lightwaves5mo ago

Modifying a query result on the client

If I got an object from query and want to modify it, would it be more like
const myvar = useQuery(api.file.myQuery)
const [myvarState, setState] = useState(myvar)
const myvar = useQuery(api.file.myQuery)
const [myvarState, setState] = useState(myvar)
or
const myvar = useQuery(api.file.myQuery)
const [myvarState, setState] = useState(undefined)
useEffect(() => {
setState(myvar)
}, [])
const myvar = useQuery(api.file.myQuery)
const [myvarState, setState] = useState(undefined)
useEffect(() => {
setState(myvar)
}, [])
3 Replies
ballingt
ballingt5mo ago
React components are functions that run from top to bottom. The first time the component renders, myvar might be undefined. Every time a new query result is received, the component will rerender and this time myvar will have a value. Your first code won't work because useState initializes the first time the component renders. I would write this code like
const myvar = useQuery(api.file.myQuery)
const [modifiedMyvar, setModifiedMyvar] = useState()
const betterMyvar = modifiedMyvar || myvar;
const myvar = useQuery(api.file.myQuery)
const [modifiedMyvar, setModifiedMyvar] = useState()
const betterMyvar = modifiedMyvar || myvar;
but it's hard to tell what you want here, what's your goal? You could indeed use a useEffect to set the state, but it's going to rerun every time the query result changes. When the query result changes to do you want that to overwrite the local modifications you've made to the variable or not? Or to zoom out, what's the goal here?
Lightwaves
LightwavesOP5mo ago
I'm querying a document. The page it's on displays the content of an array of objects in the document This page also lets you add something to that array. Usually I would either change the doc in the db and re-query the document to update the value or change the document in the db and update the frontend value with whatever was supposed to be added to the db. basically i want to change the value of myvar at some point, but i need it to be a state variable to do that, so what's the better way of making a query result a state variable Or wait maybe im just misunderstanding how this works and "myvar" magically updates if I run a mutation I guess that is so my bad I think I misread the docs

Reactivity: clients can subscribe to queries to receive new results when the underlying data changes.

To have these attributes the handler function must be deterministic, which means that given the same arguments (including the query context) it will return the same response.

Reactivity: clients can subscribe to queries to receive new results when the underlying data changes.

To have these attributes the handler function must be deterministic, which means that given the same arguments (including the query context) it will return the same response.
I thought you had to do something special to do this, not that it did it as a default
ballingt
ballingt5mo ago
Yeah this is what useQuery() does, it contains a setState that causes the component to rerender whenever the query result changes on the server. You can do things like you were describing for local-only updates, you create new variables that are based on the useQuery return value but may be something new — but it should be rare to need this, instead you can wait for the useQuery result to update, or use the built-in optimistic updates https://docs.convex.dev/client/react/optimistic-updates if you need less latency

Did you find this page helpful?