是否有一种方法来初始化一个Xstate状态机使用从Firebase返回的承诺?



我正在尝试使用Firebase持久化状态。我目前正在使用一个'saveState'功能,它可以很好地将最新状态保存到Firebase。

现在我希望能够根据Firebase中最近保存的状态初始化状态机。在下面的代码中,我试图使用我的"loadState"函数为Xstate提供一个配置对象。它当前返回一个promise,其中包含正确的状态配置。

下面是我的saveState代码:

//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: Cannot read property 'data' of undefined"我认为这是因为promise还没有解决,导致试图读取未定义的值。

这是可能的还是我做错了?

我对这一切都很陌生,任何指导都会很感激。谢谢你。

我想你可以使用useEffect来更新你的状态机。

如何在状态机内调用取?


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',
}
});

相关内容

  • 没有找到相关文章

最新更新