异步更新 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
来修复它
这些是我执行的步骤
- 像我们在普通 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
})
- 将其导出为
context
export default createContext(new MyFormsStore());
- 使用
useContext
钩子 将商店作为功能组件
const Forms = observer((props) => {
const store = useContext(MyFormsStore)
.
.
.
- 使用
useEffect
挂钩从 firestore 获取数据
useEffect(() => {
store.initForms(user_id);
}, []);
- 检查商店是否已经初始化,它是渲染它
{
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
我正在尝试使用 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
这些是我执行的步骤
- 像我们在普通 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
})
- 将其导出为
context
export default createContext(new MyFormsStore());
- 使用
useContext
钩子 将商店作为功能组件
const Forms = observer((props) => {
const store = useContext(MyFormsStore)
.
.
.
- 使用
useEffect
挂钩从 firestore 获取数据
useEffect(() => {
store.initForms(user_id);
}, []);
- 检查商店是否已经初始化,它是渲染它
{
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