【问题标题】:Atom dictionary structure原子字典结构
【发布时间】:2021-11-10 05:45:41
【问题描述】:

我从我的 react 应用程序中的 websocket 接收数据。数据包含股票代码的价格:

{symbol: "aapl", price: 150}

我想将每只股票的价格保存在单个 Atom 中,其中键是代码,数据是价格。可能有数千个原子,每个原子对应一个独特的股票。

有没有一种方法可以动态地创建一个新的 Atom,设置(或更新)它的数据,并在应用程序的其他地方读取 Atom 状态?本质上是一个 Atom 字典,其中键是股票代码,状态是股票价格。


编辑: 这应该更清楚地说明我的问题: https://github.com/facebookexperimental/Recoil/issues/1406

上下文:我使用 websocket 来传输股票价格。实时数据每 0.25 秒打包一次,包含数百个股票价格,格式如下: {符号:“aapl”,价格:150}

问题:我需要为每只股票创建一个独立的状态,在数据进入时更新它们的价格。它还需要高性能,因为有时我每秒收到 8000 只股票。股票价格将用于整个应用程序的组件中,其中一些根本不连接到父 websocket 组件。

据我所知有两种选择:

创建一个包含整个 websocket 消息的大 Atom,然后订阅这个大块状态

-这会导致所有订阅的组件立即更新,不是吗?

为每个唯一的股票生成一个 Atom,并在收到新的股票价格时更新该 atom

-我不知道如何在 Recoil 中做到这一点

本质上,它归结为一个键值对,其中键是股票代码,值是存储价格状态的 Atom。有没有办法可以创建这样的结构并允许独立组件订阅这些 Atom?例如。组件“X”订阅与股票“AAPL”对应的状态...有什么想法吗?

【问题讨论】:

  • 你的意思是全局状态吗?就像当库存发生变化(添加、删除、修改等)时,您的 UI 也会发生一些变化?
  • @MatthewKwong 是的,但不是一个大州。我需要每个股票的状态,在我的情况下将是数千个。我更喜欢许多州的原因是我可以刷新一个股票而不刷新其他股票。
  • 我想你误解了状态是如何工作的,如果你有一个数组状态,修改一个元素不一定会导致所有依赖它的组件重新渲染。这是一个漫长的故事。

标签: reactjs recoiljs


【解决方案1】:

因为您正在寻找全局状态管理框架/工具。你有几个选择。

React Context - 如果你不想要任何 3rd 方包

React Redux - 基本上是 React 全局状态管理的行业标准。

MobX - 用不同的方法做同样的工作。通常比 Redux 快,但不太受欢迎。

【讨论】:

  • 我正在使用 Recoiljs 进行状态管理。无论如何,React 上下文都不能满足我的需求。
【解决方案2】:

要回答我自己的问题。迟到总比没有好。

我在atoms.js中定义了原子

import { atomFamily } from "recoil";

export const stockAtom = atomFamily({
    key: "symbol",
    default: {},
});

在我的设置器文件中(我想设置原子值):

import { useRecoilTransaction_UNSTABLE } from "recoil";
import { stockAtom } from "./atoms";
  // ... functional component
  const updateState = useRecoilTransaction_UNSTABLE(
    ({ set }) => (stockObj) => {
      for (const stock of stockObj) {
        // set the atom of stock.sym to the jsondata from the websocket
        set(stockAtom((stock.sym).toLowerCase()), stock);
      }
    },
    []
  );

  // websocket on message
  const _onMessage = (msg) => {
    const data = JSON.parse(msg.data)
    updateState(data)
  }
  // ...

然后在我想消耗/获取原子的文件中:

import { stockAtom } from "./atoms";
import { useRecoilValue } from "recoil";
// passed stock sytmbol as props string
const WatchlistItem = (props) => {
  // consume the stock price of atom with key props.symbol
  const symbolData = useRecoilValue(stockAtom(props.symbol));
  return (<div> symbolData["price"]</div>);
}

我建议对对象/dicts 进行错误处理,我在本示例中省略了这一点

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-22
    • 1970-01-01
    • 2011-06-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多