React-Query: 单击按钮时如何使用 Query

我是这个 反应查询反应查询库的新手。

我知道当我想要获取数据时,我可以用这个库来做类似的事情:

const fetchData = async()=>{...}


// it starts fetching data from backend with this line of code
const {status, data, error} = useQuery(myKey, fetchData());

有用。但是如何只在单击按钮时触发数据获取呢?,我知道我可能会做一些像 <Button onPress={() => {useQuery(myKey, fetchData())}}/>,但如何管理返回的数据和状态..。

95797 次浏览

You have to pass the manual: true parameter option so the query doesn't fetch on mount. Also, you should pass fetchData without the parentheses, so you pass the function reference and not the value. To call the query you use refetch().

const {status, data, error, refetch} = useQuery(myKey, fetchData, {
manual: true,
});


const onClick = () => { refetch() }


Refer to the manual querying section on the react-query docs for more info https://github.com/tannerlinsley/react-query#manual-querying

Looks like the documentation changed and is missing the manual querying section right now. Looking at the useQuery API however, you'd probably need to set enabled to false, and then use refetch to manually query when the button is pressed. You also might want to use force: true to have it query regardless of data freshness.

According to the API Reference, you need to change the enabled option to false to disable a query from automatically running. Then you refetch manually.

// emulates a fetch (useQuery expects a Promise)
const emulateFetch = _ => {
return new Promise(resolve => {
resolve([{ data: "ok" }]);
});
};


const handleClick = () => {
// manually refetch
refetch();
};


const { data, refetch } = useQuery("my_key", emulateFetch, {
refetchOnWindowFocus: false,
enabled: false // disable this query from automatically running
});


return (
<div>
<button onClick={handleClick}>Click me</button>
{JSON.stringify(data)}
</div>
);

Working sandbox here  

Bonus: you can pass anything that returns a boolean to enabled. That way you could create Dependant/Serial queries.

// Get the user
const { data: user } = useQuery(['user', email], getUserByEmail)
 

// Then get the user's projects
const { isIdle, data: projects } = useQuery(
['projects', user.id],
getProjectsByUser,
{
// `user` would be `null` at first (falsy),
// so the query will not execute until the user exists
enabled: user,
}
)

There is another way to do this that also works if you want to trigger multiple refetches.

const [fetch, setFetch] = useState(null);
const query = useQuery(["endpoint", fetch], fetchData);


const refetch = () => setFetch(Date.now());


// call the refetch when handling click.

If you want to refetch multiple entities you could have a top level useState that is called for instance fetchAll and:

...
const query = useQuery(["endpoint", fetch, fetchAll], fetchData);
...

and this code will also trigger if you press a button to fetch all.

You can try this version:

const fetchData = async()=>{...}


// it starts fetching data from backend with this line of code
const {status, data, error, refetch } = useQuery(
myKey,
fetchData(),
{
enabled: false,
}
);
const onClick = () => { refetch() }
// then use onClick where you need it

From documentation Doc:

enabled: boolean

  • Set this to false to disable this query from automatically running.
  • Can be used for Dependent Queries.

refetch: (options: { throwOnError: boolean, cancelRefetch: boolean }) => Promise<UseQueryResult>

  • A function to manually refetch the query.
  • If the query errors, the error will only be logged. If you want an error to be thrown, pass the throwOnError: true option
  • If cancelRefetch is true, then the current request will be cancelled before a new request is made

you can use useLazyQuery()

import React from 'react';
import { useLazyQuery } from '@apollo/client';


function DelayedQuery() {
const [getDog, { loading, error, data }] = useLazyQuery(GET_DOG_PHOTO);


if (loading) return <p>Loading ...</p>;
if (error) return `Error! ${error}`;


return (
<div>
{data?.dog && <img src={data.dog.displayImage} />}
<button onClick={() => getDog({ variables: { breed: 'bulldog' } })}>Click me!</button>
</div>
);
}

reference: https://www.apollographql.com/docs/react/data/queries/#manual-execution-with-uselazyquery

At first react query gives us enabled option and by default it is true

const fetchData = async()=>{...}


const {status, data, error , refetch} = useQuery(myKey, fetchData() , {
enabled : false
}
);


<button onClick={() => refetch()}>Refetch</button>