首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >有没有一种更干净的方式来组织这种recoilJS状态?

有没有一种更干净的方式来组织这种recoilJS状态?
EN

Stack Overflow用户
提问于 2021-01-13 13:55:58
回答 1查看 61关注 0票数 1

我刚刚了解了recoilJS,并一直在尝试使用它,我有一个问题,我所做的是否被认为是“正确的”。我的代码可以工作,但感觉很奇怪。

我有以下React函数组件:

代码语言:javascript
复制
export const TimerPanel: FC = () => {
  const gameState = useRecoilValue<GameState>(HeaderAtoms.gameState);
  const timerCount = useRecoilValue(HeaderAtoms.timerCount);
  const setTimerCounter = useSetRecoilState(HeaderAtoms.timerCounter);

  useEffect(() => {
    if (gameState === GameState.IN_PROGRESS && timerCount < 1000) {
      window.setTimeout(() => {
        setTimerCounter(timerCount + 1);
      }, 1000);
    }
  });

  return <NumberPanel num={timerCount} />;
};

其中相关的原子和选择器定义为:

代码语言:javascript
复制
export const timerCount = atom<number>({
  key: 'Header.timerCount',
  default: 0
});

export const timerCounter = selector<number>({
  key: 'Header.timerCounter',
  get: ({ get }) => {
    return get(timerCount);
  },
  set: ({ get, set }, newCount) => {
    if (get(gameState) === GameState.NEW) {
      set(timerCount, 0);
    } else if (get(gameState) === GameState.IN_PROGRESS) {
      set(timerCount, newCount);
    }
  }
});

基本上,当游戏开始时,TimerPanel会在游戏进行中的每一秒由1递增计时器显示。如果用户重置游戏(GameState.NEW),timerCount将重置回零。如果原子/选择器没有正确完成,游戏状态和计时器计数将重置,但计时器仍在运行,并且仍将再次更新TimerPanel,因此会出现竞争情况。这就是为什么我在选择器的set属性中有if块的原因。

基本上,我担心我的timerCounter选择器是timerCount状态的一个美化的过滤器/直通实体,我想知道是否有更好的方法来处理这种用例。

EN

回答 1

Stack Overflow用户

发布于 2021-05-20 05:21:27

如果您关心的是竞态条件,在您的代码中,我看不到您的计时器会如何计时。setTimeout将会滴答一次。

不管怎样,你有两个状态,游戏状态和计时器状态。你想在游戏状态改变时重置计时器。在游戏状态选择器中做这件事怎么样?或者将逻辑移动到自定义钩子中,并直接对这两个状态进行操作。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65696399

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档