我有一个钩子
useGetFooId
,它尝试使用后备逻辑从 Redux 存储中获取 Foo 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
重写您的自定义,以直接使用商店对象而不是无法有条件调用的
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;
};