异步更新 mobx 上的商店反应挂钩

update store on mobx react hook asynchronously

我正在尝试使用 react hooks 和 mobx 将数据从 firestore 异步获取到我的本地状态,但不知道如何在从 firestore 获取数据后更新存储。我用过https://github.com/IjzerenHein/firestorter/blob/master/docs/API.md#Collection+query

我的店铺

    const store = useObservable({
        forms: [],

        async initForms(user_id) {
            console.log(user_id);
            my_forms.query = ref =>
                ref
                    .where('userId', '==', user_id)
                    .limit(20);

            let obj = {};
            const arr = [];
            my_forms.docs.forEach((doc, i) => {
                obj = {
                    key: i + 1,
                    title: doc.data.title,
                    id: doc.id,
                    tags: doc.data.tags,
                    category: doc.data.category,
                    locked: doc.data.locked

                };
                arr.push(obj);
            });
           //i can see records from firestore
           console.log('arr',arr);
           return arr;

        },
    })

我是如何尝试更新商店的

useEffect(() => autorun(() => {
        store.forms=store.initForms(user_id);
    }),[]);
store.forms && (
                        store.forms.length > 0 ? (
                                <FuseAnimateGroup
                                    enter={{
                                        animation: "transition.slideUpBigIn"
                                    }}
                                    className="flex flex-wrap py-24"
                                >
                                    {store.forms.map((f) => {

好吧,我通过使用经典的 mobx 商店并将它们用作 context

来修复它

这些是我执行的步骤

  1. 像我们在普通 React 项目中所做的那样创建经典的 mobx 存储
export class MyFormsStore {
    forms: []

    async initForms(user_id) {
        console.log(user_id);
        my_forms.query = ref =>
            ref
                .where('userId', '==', user_id)
                .limit(20);
        await my_forms.fetch();
        let obj = {};
        const arr = [];
        my_forms.docs.forEach((doc, i) => {
            obj = {
                key: i + 1,
                title: doc.data.title,
                id: doc.id,
                tags: doc.data.tags,
                category: doc.data.category,
                locked: doc.data.locked

            };
            arr.push(obj);
        });
        this.forms = arr;
    }
}

decorate(MyFormsStore, {
    forms: observable
}) 
  1. 将其导出为 context
export default createContext(new MyFormsStore());
  1. 使用 useContext 钩子
  2. 将商店作为功能组件
const Forms = observer((props) => {

    const store = useContext(MyFormsStore)
    .
    .
    .

  1. 使用 useEffect 挂钩从 firestore 获取数据
    useEffect(() => {
          store.initForms(user_id);
    }, []);
  1. 检查商店是否已经初始化,它是渲染它
    {
       store.forms !== undefined && (
           store.forms.length > 0 ? (
        //render

我仍在寻找如何记忆昂贵的函数,这样我就可以避免在每次渲染时使用 useMemo 调用它们。反馈将不胜感激

您不需要 useEffect 来更新 Mobx 跟踪的数据。 最简单的方法是使用 MobX 中的 runInAction。 因此,当您的异步功能最终得到解决时,您可以使用 runInAction 来更新商店。这最终将触发使用该特定数据的反应组件的渲染。

像这样:

    async fetchProjects() {
        this.githubProjects = []
        this.state = "pending"
        try {
            const projects = await fetchGithubProjectsSomehow()
            const filteredProjects = somePreprocessing(projects)
            // after await, modifying state again, needs an actions:
            runInAction(() => {
                this.state = "done"
                this.githubProjects = filteredProjects
            })
        } catch (error) {
            runInAction(() => {
                this.state = "error"
            })
        }
    }

您可以在官方文档中阅读更多内容: Writing asynchronous actions