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

标签 reactjs react-hooks recoiljs

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

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

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

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

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

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

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

最佳答案

问题一

习惯空渲染组件,你几乎无法使用 Recoil 避免它们,更一般地说,这个 hooks-first React 世界 😉

关于函数内的 useRecoilValue:你是对的,你应该利用 useRecoilCallback 来完成这类任务。使用 useRecoilCallback,您有一个中心点,您可以在其中立即获取和设置您想要的任何内容。看看这个working 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
  • 它使用 ID 从原子家族中检索所有汽车 const car = await snapshot.getPromise(cars(carId));

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

问题2

您的用例有几种方法:

  • 在应用启动时创建空原子,更新它们并在最后保存它们。这是什么my CodeSandbox does

  • 做同样的事情,但通过 RecoilRoot' initialState prop 初始化原子

  • Recoil 正在更新每个原子的变化。这可以通过 useRecoilTransactionObserver 实现但请注意,它目前被标记为不稳定。很快就会有一种新的方法来做同样的事情(我猜),但目前这是唯一的解决方案

后者是“更聪明”的方法,但它实际上取决于您的用例,您是否真的想在每个原子更新时更新 JSON 取决于您 😉

希望对你有帮助,如果我遗漏了什么,请告诉我😊

关于reactjs - 使用 Recoil 创建和读取数千个项目的状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63038077/

相关文章:

javascript - 增加数组中对象的数量Javascript,React,RecoilJs

javascript - 如果满足条件可以清除setInterval吗?不使用 componentDidMount?

javascript - react native : Rendering text from a function

javascript - 在 React 中使用文本区域提交表单

javascript - 在页面加载时 react js 调用 api

reactjs - 在 React 中,使用 TypeScript,如何使用 RefForwardingComponent 和 forwardRef 将 ref 传递给自定义组件?

javascript - 使用断言 Expect(xhr.requestBody.test).to.not.exist 运行 cypress 测试用例,但 eslint 抛出错误

javascript - 在 React Js 中更改图像 onClick

next.js - 使用 Next.js 13(应用程序路由器方法)结构将 RecoilRoot 集成到 Next.js 中

javascript - 有没有办法在组件之外更新 recoilJS 的状态?