我是 xState 的新手,想将现有的应用程序从 redux 迁移到 xState(我的主要动机是完全摆脱应用程序中的 redux 代码)这样做我已经关注了一些链接但停留在导航部分。让我解释一下,我试图通过以下场景通过 xState 实现:我的代码homeScreen.js、searchResult.js和myMachine.js中有三个文件,其中包含状态逻辑。主屏幕包含一些输入字段和一个搜索按钮,当用户点击搜索按钮时,它将调用 API,如果成功获取结果,则在结果屏幕上导航并将结果传递到结果屏幕。
myMachine.js // 包含机器逻辑
import { Machine } from "xstate"
const persist = [(ctx, e) => {
try {
ctx.searchFormData = e.formData || ctx.searchFormData
ctx.currentSearchPage = e.currentSearchPage || ctx.currentSearchPage
switch (e.type) {
case "done.invoke.call-search-api":
ctx.searchResults = e.data && e.data.results
break
default:
console.log("> Non-persisted event: ", e.type)
break
}
} catch (err) {
console.log('Error in Persist context: '+err)
}
}]
const searchResultsLoadedEvents = {
MORE_SEARCH_RESULTS: {
target: "searchResultsPaginating",
actions: [...persist],
},
}
const states = {
formVisible: {
on: {
SUBMIT: {
target: "searchResultsLoading",
actions: [...persist],
}
},
entry: ["retrievePreviousContext", "setInitialContext"],
},
searchResultsLoading: {
invoke: {
id: "call-search-api",
src: "callSearchAPI",
onDone: {
target: "searchResultsLoaded",
actions: [...persist],
},
},
on: {},
entry: ["logSearchFormData"],
},
searchResultsLoaded: {
entry: ["loadSearchResults", "incrementCurrentSearchPage"],
on: searchResultsLoadedEvents
}
}
const myMachine = Machine({
id: 'machineFirst',
initial: "formVisible",
states
})
export default myMachine
主屏幕 /index.js
import myMachine from "./myMachine" import {Navigation} from "react-native-navigation"; import {useMachine} from "@xstate/react" const Home = props => { const [current, send] = useMachine(myMachine) const state = current.value const context = current.context if (current.context.searchResults && current.context.searchResults.data && current.context.searchResults.data.length > 0) { Navigation.push(props.componentId, { component: {name: "screen.SearchResult"}}) // which i am trying to rid of redux and want to use xState navigation } return ( <Container style={{marginTop: 10, marginHorizontal: 15}}> {/* here i have some input fields and search button on tapping on search button tap, i call send("SUBMIT",{form body param}) of machine code*/} </Container> )} export default Home;
3.searchResult.js
import React, { useEffect} from "react";
import {useMachine} from "@xstate/react"
import myMachine from "./myMachine"
import {View} from "react-native";
const SearchResult = props => {
const [current, send] = useMachine(myMachine) // when i use this line it will reset state to initial state "formVisible" even my last state was "searchResultsLoaded" and it also clear the context data
const state = current.value
const context = current.context
useEffect(() => {
if(current && current.value && current.value === 'searchResultsLoaded'){
// assign the response result which i am getting as an response of search api call
}
}, [current.value ]);
return(
<View style={[{flex: 1, backgroundColor: '#f8f9fb'}]}>
{/*here i show the list */}
</View>
)
}
export default SearchResult
在上面的代码中,我还有一些疑问,如下所示:
- 我需要为每个屏幕创建单独的机器吗?
- 如果答案是肯定的,那么我如何管理每个屏幕的单个机器?
- 如果没有,我如何创建一个机器实例(它不会将机器重置为其初始状态值),我可以与每个屏幕共享或使用它,并保持/保持状态的最后转换和存储的上下文值?
- 如何使用 xState 管理屏幕导航?
注意:要做到这一点,我已经点击了这个不起作用的链接https://codesandbox.io/s/ykmykxnm3z。
提前致谢。