使用 Recoil 创建和读取数千个项目的状态
Create and Read State for thousands of items using Recoil
我刚开始在一个新项目中使用 Recoil,我不确定是否有更好的方法来完成这个。
我的应用程序是一个基本编辑包含对象数组的 JSON 文件的界面。它读入文件,根据特定 属性 将对象分组到选项卡中,然后用户可以导航选项卡,查看每个选项卡的几百个值,进行更改,然后保存更改。
我正在使用反冲,因为它允许我从我的应用程序中的任何位置访问每个输入的状态,这使得保存更容易 - 理论上...
为了为 JSON 文件中的每个对象生成状态,我创建了一个 returns null
的组件,然后映射到初始数组,创建组件,它使用 AtomFamily 创建 Recoil 状态,然后还将 ID 保存到另一个 Recoil 状态,这样我就可以保留所有内容的列表。
问题 1这些是更好的方法吗? null
组件感觉不对,但是将整个数组存储在单个状态中会导致在每次按键时重新呈现 everything。
为了保存数据,我有一个调用函数的按钮。该函数只需要获取 ID,遍历它们,获取每个 ID 的状态,然后将它们推入数组。我也使用 Selector 完成了此操作,但问题是由于 Hooks 规则,我无法从函数调用 getRecoilValue - 但如果我将值提供给父组件,它会再次减慢一切。
问题 2 我很确定我错过了考虑存储状态和使用挂钩的正确方法,但我还没有找到任何用于此特定用途的示例case - 需要预先生成状态,然后在保存时再次访问它。有什么指导吗?
问题 1
习惯空渲染组件,你几乎无法通过 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));
中检索所有汽车
所有这些都在一个中心点,没有钩子,也没有订阅原子更新的组件。
问题 2
您的用例有几种方法:
在应用程序启动时创建空原子,更新它们,最后保存它们。这就是 my CodeSandbox does
做同样的事情但是通过RecoilRoot
' initialState
prop
初始化原子
Recoil 正在更新每个原子的变化。 useRecoilTransactionObserver
可以做到这一点,但请注意,它目前被标记为不稳定。很快就会有一种新的方法来做同样的事情(我猜),但目前这是唯一的解决方案
后者是“更聪明”的方法,但它实际上取决于您的用例,是否真的想在每个原子更新时更新 JSON 取决于您自己
希望对您有所帮助,如果我遗漏了什么请告诉我
我刚开始在一个新项目中使用 Recoil,我不确定是否有更好的方法来完成这个。
我的应用程序是一个基本编辑包含对象数组的 JSON 文件的界面。它读入文件,根据特定 属性 将对象分组到选项卡中,然后用户可以导航选项卡,查看每个选项卡的几百个值,进行更改,然后保存更改。
我正在使用反冲,因为它允许我从我的应用程序中的任何位置访问每个输入的状态,这使得保存更容易 - 理论上...
为了为 JSON 文件中的每个对象生成状态,我创建了一个 returns null
的组件,然后映射到初始数组,创建组件,它使用 AtomFamily 创建 Recoil 状态,然后还将 ID 保存到另一个 Recoil 状态,这样我就可以保留所有内容的列表。
问题 1这些是更好的方法吗? null
组件感觉不对,但是将整个数组存储在单个状态中会导致在每次按键时重新呈现 everything。
为了保存数据,我有一个调用函数的按钮。该函数只需要获取 ID,遍历它们,获取每个 ID 的状态,然后将它们推入数组。我也使用 Selector 完成了此操作,但问题是由于 Hooks 规则,我无法从函数调用 getRecoilValue - 但如果我将值提供给父组件,它会再次减慢一切。
问题 2 我很确定我错过了考虑存储状态和使用挂钩的正确方法,但我还没有找到任何用于此特定用途的示例case - 需要预先生成状态,然后在保存时再次访问它。有什么指导吗?
问题 1
习惯空渲染组件,你几乎无法通过 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>;
};
如你所见:
通过
检索所有idconst ids = await snapshot.getPromise(carIds);
它使用 id 从原子家族
中检索所有汽车const car = await snapshot.getPromise(cars(carId));
所有这些都在一个中心点,没有钩子,也没有订阅原子更新的组件。
问题 2
您的用例有几种方法:
在应用程序启动时创建空原子,更新它们,最后保存它们。这就是 my CodeSandbox does
做同样的事情但是通过
初始化原子RecoilRoot
'initialState
propRecoil 正在更新每个原子的变化。
useRecoilTransactionObserver
可以做到这一点,但请注意,它目前被标记为不稳定。很快就会有一种新的方法来做同样的事情(我猜),但目前这是唯一的解决方案
后者是“更聪明”的方法,但它实际上取决于您的用例,是否真的想在每个原子更新时更新 JSON 取决于您自己
希望对您有所帮助,如果我遗漏了什么请告诉我