当访问 Redux 存储时,可以安全地从 Redux Provider 外部调用钩子?

问题描述 投票:0回答:1

我有一个钩子

useGetFooId
,它尝试使用后备逻辑从 Redux 存储中获取 Foo ID:

  1. 如果 Foo ID 在 Redux 存储中设置,它将从那里返回 ID(但预计在某些情况下,它不会在 Redux 存储中设置)。
  2. 否则,如果无法从 Redux 存储中获取 Foo ID,则会回退到尝试从其他一些不太可靠的地方获取 ID。

看起来像:

const useGetFooId = () => {
  const { fooId: fooIdFromSelector } = useSelector(uiSelector);
  const fooIdFromLessReliablePlace = getFooIdFromLessReliablePlace();
  const fooIdFromVeryUnreliablePlace = getVeryUnreliableFooId();
  return fooIdFromSelector ?? fooIdFromLessReliablePlace ?? fooIdFromVeryUnreliablePlace ?? null;
}

现在,我想让

useGetFooId
能够安全地从 Redux Provider 外部调用。(Foo ID 与应用程序根部的错误边界组件中的某些显示逻辑相关)。现在,如果从提供者外部调用它,则会收到此错误:
Cannot read properties of null (reading 'store')

所需的行为基本上是:如果从选择器外部调用

useGetFooId
,则它使用与选择器中未定义
fooId
相同的后备逻辑(因此,它应该返回
fooIdFromLessReliablePlace ?? fooIdFromVeryUnreliablePlace ?? null
)。

是否有一种受支持的方法,仅在 Provider 可用时有条件地访问 Redux 存储,或者其他什么?我本来想将它包装在 try/catch 中,但这似乎违反了钩子规则:https://github.com/facebook/react/issues/16026

react-redux
1个回答
0
投票

重写您的自定义,以直接使用商店对象而不是无法有条件调用的

useSelector
钩子来订阅商店的更改,例如不能在
try/catch
中有条件地调用。

请参阅store.subscribe

使用

useEffect
钩子实例化一个侦听器,该侦听器可以从存储中选择当前
fooId
值并将其保存到本地 React 状态中。您可以将商店订阅逻辑包含在
try/catch
中。

import { store } from '../path/to/store';

const useGetFooId = () => {
  const [fooIdFromSelector, setFooIdFromSelector] = React.useState(null);

  React.useEffect(() => {
    try {
      const unsubscribe = store.subscribe(() => {
        const { fooId } = uiSelector(store.getState());
        setFooIdFromSelector(fooId);
      });

      return unsubscribe;
    } catch(error) {
      // some error happened during the store subscription
      // handle/log/ignore/etc, it's up to you
    }
  }, []);

  const fooIdFromLessReliablePlace = getFooIdFromLessReliablePlace();
  const fooIdFromVeryUnreliablePlace = getVeryUnreliableFooId();

  return fooIdFromSelector
    ?? fooIdFromLessReliablePlace
    ?? fooIdFromVeryUnreliablePlace
    ?? null;
};
© www.soinside.com 2019 - 2024. All rights reserved.