react-easy-state - 一个商店通过去抖动触发另一个商店的变化

react-easy-state - one store triggering change in other with debounce

我正在尝试使用 react-easy-state 库解决以下模式:例如,我有两个包含一个字符串的商店:

filter = store({
    search : ""
})

backendFilter = store({
   search : ""
})

我希望当我对过滤器中的搜索调用更改时,它会更改后端过滤器中的值,但会去抖动。

我的想法是:

filter = store({
   search : "",
   setFilter(value) {
      filter.search=value;
      backendFilter.setBackendSearchString(value);
   })
}

backendFilter = store({
   search : "",
   setBackendSearchString(string) {
        debounce(
            () => {
                backendFilter.search = string;
            },
            600,
            true
        )();
   },
})

但不幸的是,这不起作用,只是延迟了更改,但是当我在输入上使用 onChange 处理程序来触发 filter.setFilter 时,backendFilter 的更改次数与过滤器一样多,只是有一点延迟。我知道在 React 组件中,问题通常是使用 useCallback,因为你必须确保你在 denounce 中调用的函数总是相同的,但找不到让它在那里工作的解决方案。提前致谢。

因为您使用的是 debounce(() => {...})(),所以每次调用 setBackendSearchString.

时基本上都是在创建一个新函数

我会改为将 setBackendSearchString 包裹在去抖动中:

backendFilter = store({
  search: "",
  setBackendSearchString: debounce(
    (string) => {
      backendFilter.search = string;
    },
    600,
    true
  ),
});

Al alternative would be to make/use a hook that creates a debounced value for you, like this one: https://github.com/xnimorz/use-debounce

tudor.gergely的答案是正确的,我只是有一些简单的特定额外想法。

您可以使用 autoEffect 为您的用例创建 "hook like" 自动派生。

import { store, autoEffect } from "@risingstack/react-easy-state";
import { debounce } from "lodash";

export const frontend = store({
  search: "",
  setSearch: ev => (frontend.search = ev.target.value)
});

export const backend = store({
  search: frontend.search,
  setSearch: debounce(search => (backend.search = search), 600)
});

autoEffect(() => backend.setSearch(frontend.search));

相关代码和框:https://codesandbox.io/s/cold-http-jsfyd?file=/src/stores.js:0-390

这样,您每次设置 frontend.search backend.search 时,也会通过去抖动进行更新。不过要小心。 autoEffect 主要用于链末端效果(如渲染),如果您过多地使用它从数据中获取数据,您将很快迷失在复杂的自动数据流中。 (这是我使用 vanilla React hooks 的问题之一)。