首页 > 解决方案 > 使用 Recoil 为数千个项目创建和读取状态

问题描述

我刚刚开始在一个新项目中使用 Recoil,我不确定是否有更好的方法来实现这一点。

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

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

为了为 JSON 文件中的每个对象生成状态,我创建了一个返回的组件,null我映射到初始数组,创建组件,该组件使用 AtomFamily 创建 Recoil 状态,然后还将 ID 保存到另一个部分Recoil 状态,所以我可以保留所有内容的列表。

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

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

问题 2我很确定我错过了考虑存储状态和使用钩子的正确方法,但是我还没有找到这个特定用例的任何示例 - 需要预先生成状态,然后访问它再次保存。有什么指导吗?

标签: reactjsreact-hooksrecoiljs

解决方案


问题 1

习惯于 null 渲染组件,你几乎无法使用 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>;
};

如你看到的:

  • 它通过const ids = await snapshot.getPromise(carIds);

  • 它使用 id 来检索 atom 家族中的所有汽车const car = await snapshot.getPromise(cars(carId));

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

问题2

您的用例有几种方法:

后者是“更智能”的方法,但它确实取决于您的用例,您可以自行考虑是否真的想在每次 atom 更新时更新 JSON

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


推荐阅读