用MobX在const函数内部反应useEffect

时间:2020-08-11 19:01:37

标签: reactjs typescript react-redux mobx-react

我有一些用Typescript编写的React Redux代码,当组件安装时,这些代码会从服务器中加载一些数据。该代码如下所示:

import { useEffect } from 'react';
import { useDispatch } from 'react-redux';
import { MyAction } from 'my/types/MyAction';

export const useDispatchOnMount = (action: MyAction) => {
    const dispatch = useDispatch();
    return useEffect(() => {
        dispatch(action);
    }, [dispatch]);
};

这很简单-它使用useEffect挂钩执行我想要的操作。现在,我需要转换代码,以便它使用MobX而不是Redux来保持持久状态。如果我有一个名为myStore的MobX存储对象,并且myStore有一个异步方法“ loadXYZ”,它可以加载一组特定的数据XYZ,我知道可以在我的组件中执行此操作:

useEffect(() => {
    async functon doLoadXYZ() {
        await myStore.loadXYZ();
    }
    doLoadXYZ();
}, []);

这确实有效,但是我想将所有这些都放到一个调用useEffect的单一箭头函数中,就像useDispatchOnMount函数一样。我不知道这样做的最好方法。有人知道该怎么做吗?

编辑:在进一步挖掘之后,它看起来越来越像我尝试使用Mobx版本会破坏Hooks的规则,即始终从功能组件的顶层调用useEffect。所以像这样显式地调用它:

export const MyContainer: React.FC = () => {
    useEffect(() => {
        async functon doLoadXYZ() {
            await myStore.loadXYZ();
        }
        doLoadXYZ();
    }, []);
    ...
};

显然是最好的选择。但这引发了一个问题:使用useDispatchOnMount的redux版本是一个坏主意吗?为什么?

1 个答案:

答案 0 :(得分:0)

如果在useEffect中不使用async / await,则可以执行此操作。如果您要获取数据,我会将其存储在myStore中,并直接在存储中使用它,而不是使用异步/等待。它可能看起来像这样:

export const SomeComp = observer(function SomeComp() {
  const myStore = useStore() // get the store with a hook or how you are getting it
  useEffect(myStore.loadXYZ, [myStore])

  return <div>{myStore.theLoadedData}</div>
})

loadXYZ中,您只是按照所需的方式存储和使用数据。观察到theLoadedData的组件将在返回时重新呈现,因此您无需在该组件中进行异步/等待。