상태 머신 및 Xstate부터 시작합니다!

소프트웨어 개발자로서 우리 모두는 어느 시점에서 상태 머신에 대해 들어봤을 것입니다. 유한 상태 머신은 일련의 입력을 기반으로 출력을 계산하거나 현재 및 이전 상태의 출력을 기반으로 다음 상태를 계산하는 것과 같은 알고리즘 설계에서 꽤 유명합니다.

들어본 적이 있는 상태 머신의 인기 있는 예가 많이 있습니다.
  • 신호등 🚦
  • 자판기 ⚒️
  • 엘리베이터🚪

  • 상태 시스템은 복잡한 규칙 및 조건 집합을 나타내는 매우 간결한 방법이므로 프런트엔드 애플리케이션에서 사용을 확장할 수 있는 방법을 알아보겠습니다.

    프론트엔드에 상태 머신이 필요한 이유는 무엇입니까?



    브라우저의 상태 관리는 특히 복잡한 상태 관리가 있는 대규모 애플리케이션에서 작업할 때 항상 까다로운 부분이었습니다. UI 프레임워크는 원하는 결과를 얻기 위해 응용 프로그램 상태를 DOM 노드로 전환하는 중요한 역할을 합니다.

    상태 머신은 응용 프로그램이 주어진 시간에 하나의 상태에만 있을 수 있도록 응용 프로그램의 상태를 모델링하는 매우 유용한 방법입니다. 이러한 모든 이점은 결국 새로운 이벤트, 새로운 코너 케이스 등이 필요한 애플리케이션의 확장과 관련된 문제를 해결하는 데 도움이 될 것입니다.

    우리의 응용 프로그램부터 시작합니다.



    Xstate를 사용하여 Vue.js에서 간단한 Todo 애플리케이션을 생성하는 것으로 시작하겠습니다.

    첫 번째 단계는 TodoList를 만드는 데 필요한 모든 가능한 UI 상태를 결정하는 것입니다. 응용 프로그램에 필요한 기본 상태와 작업을 적어두기 시작했습니다.
  • 유휴, 로드 중, 해결됨, 거부됨과 같은 몇 가지 기본 상태가 있습니다
  • .
  • 응용 프로그램에 필요한 일련의 작업은 목록 업데이트, 새 할 일 항목 만들기, 할 일 항목 업데이트 및 할 일 항목 삭제입니다
  • .
  • 편집, 삭제 및 생성은 사용자가 세 가지 작업을 모두 동시에 수행할 수 있으므로 병렬 상태가 됩니다.

  • 위의 포인터를 사용하여 내 애플리케이션의 모든 상태와 작업을 다루는 Xstate Viz의 기본 상태 차트를 만들었습니다.



    상태 기계 정의 코드:

    Machine(
      {
        id: 'Todo',
        initial: 'idle',
        context: {
          user: null,
          todoList: [],
          delay: 0
        },
        states: {
          idle: {
            on: {
              fetch: 'list'
            }
          },
          list: {
            invoke: {
              id: 'fetchList',
              src: (context, event) => {
                return context.todoList
              },
              onDone: {
                target: 'resolved'
              },
              onError: 'rejected'
            },
            on: {
              listItems: {
                target: 'todoItemActions',
                actions: 'addListItem'
                //   actions: ['fetchListItems']
              }
            }
          },
          resolved: {
            type: 'final'
          },
          rejected: {
            on: {
              fetch: 'list'
            }
          },
          todoItemActions: {
            type: 'parallel',
            states: {
              createTodoItem: {
                initial: 'add_details',
                states: {
                  idle: {
                    on: {
                      create: 'add_details'
                    }
                  },
                  add_details: {
                    on: {
                      fillDetails: {
                        target: 'createSuccess',
                        actions: 'createNewTodoItem'
                      }
                    }
                  },
                  createSuccess: {}
                }
              },
              deleteTodoItem: {
                initial: 'idle',
                states: {
                  idle: {
                    on: {
                      select_item: 'deleteItem'
                    }
                  },
                  deleteItem: {
                    on: {
                      delete: {
                        target: 'deleteSuccess',
                        actions: 'deleteTodoItem'
                      }
                    }
                  },
                  deleteSuccess: {}
                }
              },
              editTodoItem: {
                initial: 'idle',
                states: {
                  idle: {
                    on: {
                      edit: 'edit_details'
                    }
                  },
                  edit_details: {
                    on: {
                      fill_details: {
                        target: 'editSuccess',
                        actions: 'editTodoItem'
                      }
                    }
                  },
                  editSuccess: {}
                }
              }
            }
          }
        }
      },
      {
        actions: {
          createNewTodoItem: (context, event) => {
            console.log('create new todo item', context)
          },
          addListItem: (context, event) => {
            console.log('add list item', context, event)
          },
          deleteTodoItem: (context, event) => {
            console.log("delete todo item", context, event)
          },
          editTodoItem:  (context, event) => {
            console.log("edit todo item", context, event)
          }
        }
      }
    )
    


    Visualizer에서 위의 상태 시스템 정의를 확인할 수 있습니다.

    다음 포스트에서는 Vue js에서 Xstate를 사용하여 Todo 앱의 통합 및 생성에 대해 다룰 것입니다.

    영감을 얻은 멋진 기사가 웹에 몇 개 있습니다. 확인해보세요!🙈
  • Robust React User Interfaces with Finite State Machines
  • Using State Machines in Vue.js with XState
  • Official Documentation
  • 좋은 웹페이지 즐겨찾기