【问题标题】:How to access cache to display data with React Query?如何使用 React Query 访问缓存以显示数据?
【发布时间】:2021-06-26 01:53:39
【问题描述】:

我的应用程序有一个用户输入一个 id 作为请求发送,并且与该 id 匹配的响应数据被呈现并缓存。

我想访问缓存,以便我还可以显示其数据,以便用户可以查看他们以前的查询。但是,我在尝试时收到此错误。 TypeError: Cannot read property 'getQueryData' of undefined.

以下是我访问缓存的尝试。

console.log(queryCache.getQueryData("rickandmorty"))
console.log(queryCache.getQueryData(["rickandmorty", idQuery]))
console.log(queryClient.getQueryData("rickandmorty"))
console.log(queryClient.getQueryData(["rickandmorty", idQuery]))

请让我知道我做错了什么。我正在使用版本"react-query": "^3.13.0"https://codesandbox.io/s/rick-and-morty-2gy8r?file=/src/App.js

const [idQuery, setIdQuery] = useState(0);
const [rickAndMortyCharacter, setRickAndMortyCharacter] = useState({});
const queryRef = useRef(null);
const { register, handleSubmit, errors, setValue, watch } = useForm({
  resolver: yupResolver(searchSchema)
});
const formId = watch("rickAndMortyId");

const handleRickAndMortyFetch = () => {
  return delay()
    .then(() => axios(`https://rickandmortyapi.com/api/character/${idQuery}`))
    .then((res) => setRickAndMortyCharacter(res.data));
};

const { isLoading, error } = useQuery(
  ["rickandmorty", idQuery],
  handleRickAndMortyFetch,
  {
    refetchOnWindowFocus: false,
    enabled: idQuery !== 0,
    useErrorBoundary: true
  }
);
const disable = isLoading || parseFloat(formId) === idQuery;
const onSubmit = (formData) => {
  setIdQuery(formData.rickAndMortyId);
};

return (
  <div>
    <ErrorBoundary
      FallbackComponent={ErrorFallback}
      onReset={() => {
        queryRef.current.focus();
      }}
      resetKeys={[idQuery]}
    >
      <div>
        <form onSubmit={handleSubmit(onSubmit)}>
          <h3>Rick and Morty</h3>
          <input
            type="number"
            name="rickAndMortyId"
            placeholder="Between 1 and 671"
            ref={register}
            disabled={isLoading}
          />
          {errors.rickAndMortyId && <span>This field is required</span>}
          {error && <p>Error occurred: {error.message}</p>}
          <button type="submit" disabled={disable}>
            Search Character
          </button>
        </form>
        <button
          onClick={() => {
            const randomId = getRandomRickAndMortyCharacterId();
            setValue("rickAndMortyId", randomId);
            setIdQuery(randomId);
          }}
        >
          Random
        </button>
      </div>
      <div>
        {isLoading && <p>Loading...</p>}
        <RickAndMortyInfo rickAndMortyCharacter={rickAndMortyCharacter} />
      </div>
      <ReactQueryDevtools initialIsOpen={true} />
    </ErrorBoundary>
  </div>
);

【问题讨论】:

    标签: reactjs react-hooks react-hook-form react-query


    【解决方案1】:

    在这段代码中:

    const [rickAndMortyCharacter, setRickAndMortyCharacter] = useState({});
    const handleRickAndMortyFetch = () => {
      return delay()
        .then(() => axio('...'))
        .then((res) => setRickAndMortyCharacter(res.data));
    };
    
    const { isLoading, error } = useQuery(
      ["rickandmorty", idQuery],
      handleRickAndMortyFetch
    );
    

    成功获取后,您将结果分配给本地状态,而不是交给react-query,因此它不知道应该缓存哪些数据。您需要像这样返回结果:

    const handleRickAndMortyFetch = () => {
      return delay()
        .then(() => axio('...'))
        .then((res) => res.data); // return instead of calling setState()
    };
    

    所以react-query 可以“捕获”它并将其放入缓存中。下一步是删除您的本地状态 rickAndMortyCharacter 并改为引用 data。是成功抓取后的解析结果。

    const {
      isLoading,
      error,
      data // remove rickAndMortyCharacter and reference this instead
    } = useQuery(
      ["rickandmorty", idQuery],
      handleRickAndMortyFetch
    );
    

    只有这样才能正常记录缓存:

    queryClient.getQueryData(["rickandmorty", 518]);
    

    现场演示

    【讨论】:

    • 感谢您的清晰解释!我发现我的错误是我将状态设置为响应数据,而不是把它交给 React-Query。
    • 你能分享我如何访问缓存中所有以前的查询而不是最近的请求吗?
    • 请再发一个问题,我有时间会回答@ln09nv2
    猜你喜欢
    • 2021-07-01
    • 1970-01-01
    • 2021-07-09
    • 1970-01-01
    • 2022-11-17
    • 1970-01-01
    • 2022-11-22
    • 1970-01-01
    • 2017-02-02
    相关资源
    最近更新 更多