在 React-Query 中订阅手动缓存?

发布于 2025-01-19 18:48:55 字数 998 浏览 2 评论 0原文

开始尝试使用react-query,并在想我是否可以用它来替代redux?我发现react-query在nextJS中更容易使用(特别是如果我想在服务器上设置状态),所以希望有一个不需要函数的useQuery,即与redux类似的工作方式useSelect

这样的事情可能吗(这不起作用,但说明了我想要实现的目标)?即使用react-query作为缓存数据,并且能够订阅该缓存数据。

function InputHeaderContainer() {
  return (
    <div>
      <InputHeader />
      <InputBar />
    </div>
  );
}

function InputBar() {
  const queryClient = useQueryClient();
  const inputValue = queryClient.getQueryData('INPUT_VALUE');

  const onSearchChange = (event) => {
    queryClient.setQueryData('INPUT_VALUE', event.target.value);
  };

  return <input onChange={onSearchChange} value={inputValue || ''} />;
}

function InputHeader() {
  const queryClient = useQueryClient();
  // getQueryData doesnt subscribe to the state and useQuery req a function :(
  const inputValue = queryClient.getQueryData('INPUT_VALUE');

  return (
    <div>
      <h2>{inputValue}</h2>
    </div>
  );
}

Started to experiment with react-query and was thinking if i could use it as a replacement for redux? I fint react-query to be easier to use in nextJS (especially if i want to set a state on the server) so hope there would be a useQuery that doesnt require a function, ie works similar to redux's useSelect.

Is something like this possible (this doesnt work but illustrates what i want to achieve)? Ie use react-query as cache data an be able to subscribe to that cache data.

function InputHeaderContainer() {
  return (
    <div>
      <InputHeader />
      <InputBar />
    </div>
  );
}

function InputBar() {
  const queryClient = useQueryClient();
  const inputValue = queryClient.getQueryData('INPUT_VALUE');

  const onSearchChange = (event) => {
    queryClient.setQueryData('INPUT_VALUE', event.target.value);
  };

  return <input onChange={onSearchChange} value={inputValue || ''} />;
}

function InputHeader() {
  const queryClient = useQueryClient();
  // getQueryData doesnt subscribe to the state and useQuery req a function :(
  const inputValue = queryClient.getQueryData('INPUT_VALUE');

  return (
    <div>
      <h2>{inputValue}</h2>
    </div>
  );
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

满栀 2025-01-26 18:48:55

所以希望有一个不需要函数的useQuery,即与redux的useSelect类似的工作方式。

你确实需要提供实际的queryFn,但这并不意味着你不能实现类似redux的状态管理:

const useTodos = (select) => useTodos(['todos'], fetchTodos, { select })

感谢select,你可以创建细粒度的订阅,比如:

const todoCount = useTodos(todos => todos.length)
const firstTodo = useTodos(todos => todos[0])

等等。当然,您可以在自定义挂钩中进一步抽象,例如 useTodoCount()

组件只会订阅 select 函数的结果,因此如果您只使用 todo 计数,则如果一个 todo 发生变化,组件将不会重新渲染,因为数组的长度保持不变。 (侧面节点:这假设设置了react-query v4或notfiyOnChangeProps: 'tracked'。否则,您仍然会看到重新渲染,因为isFetching转换) 。

另请注意,每个订阅都会触发后台重新获取。如果您计划多次使用自定义挂钩,这可能过于激进。这可以通过在查询中设置 staleTime 来最好地自定义。这个时间告诉react-query 资源被认为是新鲜的时间。只要数据是新鲜的,数据就会仅从缓存中出来(无后台更新)。要仅获取一次,请设置 staleTime: Infinityy。

so hope there would be a useQuery that doesnt require a function, ie works similar to redux's useSelect.

You do need to provide the actual queryFn, but that doesn't mean that you cannot achieve redux like state management:

const useTodos = (select) => useTodos(['todos'], fetchTodos, { select })

Thanks to select, you can create fine-grained subscriptions, like:

const todoCount = useTodos(todos => todos.length)
const firstTodo = useTodos(todos => todos[0])

and so on. You can of course abstract that further away in custom hooks, like useTodoCount().

Components will only be subscribed to the result of the select function, so if you only use the todo count, the component won't re-render if one todo changes because the length of the array stays the same. (side node: This assumes either v4 of react-query, or notfiyOnChangeProps: 'tracked' being set. Otherwise, you'll still see re-renders because isFetching transitions).

Also, be advised that every subscription triggers a background refetch. This can be too aggressive if you plan on using the custom hook multiple times. This can be best customized by setting a staleTime no your query. This time tells react-query how long a resource is considered fresh. As long as it is fresh, data will come out of the cache only (no background updates). To only fetch once, set staleTime: Infintiy.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文