상태 머신: 이것이 상태여야 합니까, 아니면 컨텍스트여야 합니까?

10869 단어 webdevxstate
상태 머신은 상태를 표현하기 위한 여러 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 데이터 등 유한하게 표현할 수 없는 모든 것이 포함됩니다.

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

    좋은 웹페이지 즐겨찾기