Search code examples
react-querytanstackreact-query

How to detect and trigger my code when initial data is fetched from useQuery()


In my React app I have a fully controlled <select>, the values of which are retrieved from the server using TanStack react-query. What I want to do is automatically select the first item only when the data is initially retrieved from the server, but not if it gets re-fetched in the background while the user is editing the form.

What I have at the moment is this:

const [selectedWidget, setSelectedWidget] = useState<string | null>(null)

const myQuery = useQuery({...})

useEffect(() => {
    if (!selectedWidget) {
        setSelectedWidget(myQuery.data?.[0]?.id ?? null)
    }
}, [myQuery.data, selectedWidget])

<select 
    value={selectedWidget ?? ""}
    onChange={e => setSelectedWidget(e.target.value)}>
    {
        myQuery.data.map(x =>
            <option key={x.id} value={x.id}>{x.description}</option>
        )
    }
</select>

It seems to work OK but the point of react-query is to stop me being reliant on useEffect(), so is there a better way to do this without it?


Solution

  • ParentComponent.tsx

    const {data: queryData, isLoading: isLoadingQueryData} = useQuery({...})
    { !isLoadingQueryData && <SelectComponent queryData={queryData}/> }
    

    SelectComponent.tsx

    const [selectedWidget, setSelectedWidget] = useState(queryData?.[0]?.id || null)
    <select 
        value={selectedWidget ?? ""}
        onChange={e => setSelectedWidget(e.target.value)}>
        {
            myQuery.data.map(x =>
                <option key={x.id} value={x.id}>{x.description}</option>
            )
        }
    </select>