使用 Recoil 创建和读取数千个项目的状态

McB*_*McB 2 reactjs react-hooks recoiljs

我刚刚开始在一个新项目中使用 Recoil,我不确定是否有更好的方法来完成此任务。

我的应用程序是一个界面,用于基本上编辑包含对象数组的 JSON 文件。它读取文件,根据特定属性将对象分组到选项卡中,然后用户可以导航选项卡,查看每个选项卡的数百个值,进行更改,然后保存更改。

我使用反冲是因为它允许我从应用程序中的任何位置访问每个输入的状态,这使得保存更容易 - 理论上......

为了为 JSON 文件中的每个对象生成状态,我创建了一个返回的组件,null并映射初始数组,创建该组件,该组件使用 AtomFamily 创建 Recoil 状态,然后还将 ID 保存到另一块反冲状态,这样我就可以保留所有内容的清单。

问题 1这是更好的方法吗?该null组件感觉不太对劲,但是将整个数组存储在单个状态中会导致每次按键时重新渲染所有内容

为了保存数据,我有一个调用函数的按钮。该函数只需要获取 ID,循环遍历它们,获取每个 ID 的状态,然后将它们推送到数组中。我也使用选择器完成了此操作,但问题是由于 Hooks 规则,我无法从函数中调用 getRecoilValue - 但如果我将该值提供给父组件,它会再次减慢一切。

问题 2我很确定我缺少考虑存储状态和使用挂钩的正确方法,但我还没有找到此特定用例的任何示例 - 需要预先生成状态,然后访问所有状态再次单击“保存”。有什么指导吗?

Nor*_*Ste 6

问题1

习惯空渲染组件,使用 Recoil 几乎无法避免它们,更一般地说,这个钩子优先的 React 世界

关于useRecoilValue函数内部:你是对的,你应该利用useRecoilCallback这种任务。有了useRecoilCallback一个中心点,您可以立即获取并设置您想要的任何内容。看一下这个工作 CodeSandbox,我在其中尝试复制(最简单的方式)您的用例。该SaveData组件(专用组件不是必需的,您可以只公开 Recoil 回调而不创建临时组件)如下

const SaveData = () => {
  const saveData = useRecoilCallback(({ snapshot }) => async () => {
    const ids = await snapshot.getPromise(carIds);
    for (const carId of ids) {
      const car = await snapshot.getPromise(cars(carId));
      const carIndex = db.findIndex(({ id }) => id === carId);
      db[carIndex] = car;
    }
    console.log("Data saved, new `db` is");
    console.log(JSON.stringify(db, null, 2));
  });

  return <button onClick={saveData}>Save data</button>;
};
Run Code Online (Sandbox Code Playgroud)

如你看到的:

  • 它通过以下方式检索所有 idconst ids = await snapshot.getPromise(carIds);

  • 它使用 ID 检索 Atom 系列中的所有汽车const car = await snapshot.getPromise(cars(carId));

所有这些都在一个中心点,没有钩子,也没有为组件订阅原子更新。

问题2

有几种方法适合您的用例:

后者是“更智能”的方法,但这实际上取决于您的用例,您可以考虑是否真的想在每个原子更新时更新 JSON

我希望它有帮助,如果我错过了什么,请告诉我