javascript - 有没有办法使用从 Firebase 返回的承诺来初始化 Xstate 状态机?
问题描述
我正在尝试使用 Firebase 保持状态。我目前正在使用“saveState”功能,该功能可以正常工作并将最新状态正确保存到 Firebase。
现在我希望能够根据 Firebase 中最近保存的状态来初始化状态机。在下面的代码中,我尝试使用我的“loadState”函数为 Xstate 提供一个配置对象。它目前返回一个带有正确状态配置的承诺。
这是我的“保存状态”代码:
//This function works fine.
function saveState(current, id){
let transactionJSON = serialize(current);
transactionJSON['createdOn'] = new Date();
return firebase.saveTransactionState({transactionJSON, transactionId:id});
}
这是我的“loadState”函数,它从 Firebase 返回一个带有正确配置信息的承诺。
function loadState(id){
return firebase.getTransactionState({transactionId:id}).then(function(querySnapshot) {
return querySnapshot.docs.map(doc => deserialize({...doc.data()}) );
});
};
现在我的问题是尝试使用上面的“loadState”函数加载 Xstate。在这里,我尝试使用 useMachine React 钩子:
const [current, send] = useMachine(transactionMachine,{
state: () => loadState(id), //Trying to do something like this, but it doesn't seem to work.
actions:{
save: () => saveState(current, id),
},
});
我最终得到错误:“TypeError:无法读取未定义的属性'数据'”,我相信这是因为承诺尚未解决,导致尝试读取未定义的值。
这甚至可能吗,还是我做错了?
我对这一切都很陌生,任何指导将不胜感激。谢谢你。
解决方案
我想您可以useEffect
在获取后使用更新您的状态机。
在状态机中调用 fetch 怎么样?
import { Machine, assign } from 'xstate';
const yourMachine = Machine({
id: 'yourStateMachine',
initial: 'fetching',
context: {
values: {
id: '', // likely need a state to initialize this value before fetching
apiDat: {}
},
},
states: {
fetching: {
invoke: {
src: ({values}) => firebase
.getTransactionState({ transactionId: values.id })
.then(function(querySnapshot) {
return querySnapshot.docs.map(
doc => deserialize({...doc.data()})
);
}),
onDone: { target: 'resolving', actions: 'cacheApiDat' },
onError: { target: 'error.fetchFailed' },
}
},
resolving: {
initial: 'delay',
states: {
delay: {
after: {
750: 'resolve'
},
},
resolve: {
always: [
{ cond: 'isSuccess', target: '#yourStateMachine.idle' },
{ cond: 'isUnauthorized', target: '#yourStateMachine.error.auth' },
],
}
},
},
error: {
states: {
fetchFailed: {
type: 'final',
},
auth: {
type: 'final',
}
}
},
idle: {
},
}
},{
actions: {
cacheApiDat: assign({ values: ({values}, event) => ({
...values,
apiDat: event.data, // save whatever values you need here
}),
}),
},
guards: {
// this requires a definition based on firebase's returned api call on a success
isSuccess: ({values}) => typeof values.apiDat.data !== 'undefined',
// this requires a definition based on firebase's returned api call when the call is unauthorized
isUnauthorized: ({values}) => typeof values.apiDat.detail !== 'undefined' && values.apiDat.detail === 'invalid_auth',
}
});
推荐阅读
- python-3.x - “系列”对象python中的日期季度
- python - Keras InvalidArgumentError:不兼容的形状:[1,8,32] 与 [1,10,32]
- petapoco - 在 PetaPoco 中,如何定义具有 2 个主键的表?
- xamarin - 如何以编程方式在 Xamarin android 中设置重力
- c++ - 从容器中的 xml 文件中提取非同质顺序数据
- function - 在 clojure 函数中使用过滤器
- angular - 在 Angular 中使用 Map 运算符转换对象
- css - 如何将预加载器加载 gif 添加到我的网站
- grails - 如何在没有cdn链接的grails 2.4.4版本中集成font-awesome 5.3
- java - Java 对象在序列化时丢失所有数据