【问题标题】:update store on mobx react hook asynchronously异步更新 mobx 反应钩子上的存储
【发布时间】:2019-12-21 18:17:40
【问题描述】:

我正在尝试使用 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) => {

【问题讨论】:

    标签: reactjs google-cloud-firestore react-hooks mobx firestorter


    【解决方案1】:

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

    类似这样的:

        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

    【讨论】:

    • 伙计,你在使用 hook 时无法避免使用效果。如何在不使用 useEffect 的情况下复制 componentDidMount?
    • 重点是您使用useEffect 只是为了触发 mobx 操作,让 mobx 处理其余的操作。
    • 谢谢伙计,在回答问题之前请先通过 react hooks,我不是在劝阻你,但很高兴删除不正确和不相关的答案,我有兴趣通过 Mobx 更新我的本地状态,我可以仅通过使用效果触发 mobx 效果,因为我正在使用钩子。您的答案 this.state 在这里根本不相关。这就是为什么我不赞成它
    【解决方案2】:

    我通过使用经典的 mobx 商店并将它们用作 context 来修复它

    这些是我做的步骤

    1. 创建经典的 mobx 商店,就像我们在正常的 react 项目中所做的那样
    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 hook 将 store 作为功能组件玩
    const Forms = observer((props) => {
    
        const store = useContext(MyFormsStore)
        .
        .
        .
    
    
    1. 使用 useEffect 挂钩从 Firestore 获取数据
        useEffect(() => {
              store.initForms(user_id);
        }, []);
    
    1. 检查store是否已经初始化,是否渲染
        {
           store.forms !== undefined && (
               store.forms.length > 0 ? (
            //render
    

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

    【讨论】:

      猜你喜欢
      • 2016-12-26
      • 2020-09-27
      • 1970-01-01
      • 2019-01-01
      • 2020-02-03
      • 1970-01-01
      • 2017-04-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多