0

我是 xState 的新手,想将现有的应用程序从 redux 迁移到 xState(我的主要动机是完全摆脱应用程序中的 redux 代码)这样​​做我已经关注了一些链接但停留在导航部分。让我解释一下,我试图通过以下场景通过 xState 实现:我的代码homeScreen.jssearchResult.jsmyMachine.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
  1. 主屏幕 /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

在上面的代码中,我还有一些疑问,如下所示:

  1. 我需要为每个屏幕创建单独的机器吗?
  2. 如果答案是肯定的,那么我如何管理每个屏幕的单个机器?
  3. 如果没有,我如何创建一个机器实例(它不会将机器重置为其初始状态值),我可以与每个屏幕共享或使用它,并保持/保持状态的最后转换和存储的上下文值?
  4. 如何使用 xState 管理屏幕导航?

注意:要做到这一点,我已经点击了这个不起作用的链接https://codesandbox.io/s/ykmykxnm3z

提前致谢。

4

0 回答 0