Как направить навигацию с помощью xState в приложении React Native

Я новичок в 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
  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.

Заранее спасибо.

0 ответов

Другие вопросы по тегам