상태 머신: 상태여야 합니까 아니면 컨텍스트에 있어야 합니까?

10836 단어 xstatewebdev
상태 머신은 상태를 표현하기 위한 여러 API를 제공합니다. 다른 도구와 마찬가지로 context 라는 저장소(일반적으로 객체로 표현됨)에 임의의 값을 보관할 수 있습니다.

이것은 양식 입력 값과 같이 시간이 지남에 따라 변경되고 업데이트를 유지해야 하는 값에 유용합니다.

import { createMachine, assign } from 'xstate';

const machine = createMachine({
  context: {
    name: '',
  },
  on: {
    CHANGE_NAME: {
      actions: assign((context, event) => {
        return {
          name: event.value,
        };
      }),
    },
  },
});

CHANGE_NAME 이벤트가 시스템으로 전송될 때마다 context 의 값을 업데이트합니다. 그런 다음 해당 값을 사용하여 UI에 값을 표시하거나 API로 보낼 수 있습니다.

XState는 또한 유한 상태를 통해 상태를 표현하는 또 다른 방법을 제공합니다. 모달을 상상해 봅시다.

const machine = createMachine({
  initial: 'closed',
  states: {
    closed: {
      on: {
        OPEN: 'open',
      },
    },
    open: {
      on: {
        CLOSE: 'close',
      },
    },
  },
});


여기서 모달의 상태는 states: {} 속성을 통해 표현되며, 각 상태에서 어떤 이벤트를 받을 수 있는지도 정의합니다. 모달이 CLOSE 일 때만 open 할 수 있으며 그 반대의 경우도 마찬가지입니다.

어느 것을 선택해야 합니까?


contextstates 중 선택이 항상 명확한 것은 아닙니다. 예를 들어 위의 모달 머신은 context를 사용하여 표현할 수 있습니다.

const machine = createMachine({
  context: {
    isOpen: false,
  },
  on: {
    OPEN: {
      actions: assign({ isOpen: true }),
    },
    CLOSE: {
      actions: assign({ isOpen: false }),
    },
  },
});


이것은 위의 상태 기반 기능과 정확히 동일한 기능을 제공합니다. 모달이 열리고 닫힐 때를 추적하고 동일한 이벤트를 보낼 수 있습니다.
statescontext를 모두 사용하여 표현할 수 있는 이유는 어떤 상태에 있든 모든 이벤트가 동일한 작업을 수행하기 때문입니다. 특정 상태에서는 불가능하다고 선언해야 하는 이벤트가 없습니다.

내가 의미하는 바를 보여주기 위해 모달 내부의 양식 입력을 상상해 봅시다. 모달이 열려 있는 동안에만 양식 입력에 대한 변경을 허용하고 싶습니다.

const machine = createMachine({
  initial: 'closed',
  context: {
    name: '',
  },
  states: {
    closed: {
      on: {
        OPEN: 'open',
      },
    },
    open: {
      on: {
        CLOSE: 'close',
        CHANGE_NAME: {
          actions: assign((context, event) => {
            return {
              name: event.value,
            };
          }),
        },
      },
    },
  },
});


모달이 closed 상태일 때 CHANGE_NAME 이벤트는 context 의 값을 변경하지 않습니다. 상태 머신은 이 점에서 훌륭합니다. 원하는 일만 발생하도록 허용합니다. 다른 예는 다음과 같습니다.
  • 이전 API 호출이 로드되는 동안 사용자가 양식을 제출하도록 허용하지 않음
  • 사용자가 아직 로그인하지 않은 경우에만 로그인하도록 허용

  • 상황에 맞게 배치하기



    궁금하시겠지만 위의 표현은 context !

    const machine = createMachine({
      context: {
        name: '',
        isOpen: false,
      },
      on: {
        OPEN: { actions: assign({ isOpen: true }) },
        CLOSE: { actions: assign({ isOpen: false }) },
        CHANGE_NAME: {
          actions: assign((context, event) => {
            // This acts as the guard to prevent editing
            // the name while it's open
            if (!context.isOpen) return {};
            return {
              name: event.value,
            };
          }),
        },
      },
    });
    


    나는 이것이 두 가지 이유로 옳지 않다고 생각한다. 첫째, 요구 사항이 증가함에 따라 논리의 복잡성도 증가합니다. 이제 모달이 closing (즉, 애니메이션) 또는 closed 일 수 있다고 상상해 봅시다. 에서 논의한 것처럼 부울의 폭발적인 증가를 곧 보게 될 것입니다.

    둘째, XState는 XState visualiser 을 통해 자동 문서화됩니다. 논리가 states로 표현될수록 시각화하기가 더 쉬워집니다. 위의 기계는 기본적으로 XState가 시각화할 수 없는 방식으로 논리가 표현된 단일 상태입니다.

    지켜야 할 규칙



    컨텍스트에서 대부분의 상태를 유지해야 합니다. 여기에는 양식 값, API 데이터 - 유한하게 표현할 수 없는 모든 것이 포함됩니다.

    그러나 상태 머신은 상태 때문에 강력합니다. 논리를 시각적으로 표현하거나 이벤트를 특정 상태로 연결하려는 경우 상태를 사용합니다.

    좋은 웹페이지 즐겨찾기