Creative Tools 편집자를 위한 상태 관리 솔루션 구축

Nov 28 2022
소개 이 기사에서는 React, Immer 및 Recoil을 접근 방식의 기초로 사용하는 크리에이티브 도구 편집기의 맥락에서 확장 가능한 상태 관리 솔루션을 설계하고 구축하는 데 대한 약간의 의견이 있는 통찰력을 공유할 것입니다. 접근 방식을 더 잘 설명하기 위해 몇 가지 코드 예제와 작은 프로토타입을 포함합니다.

소개

이 기사에서는 React, Immer 및 Recoil 을 접근 방식의 기초로 사용하는 크리에이티브 도구 편집기의 맥락에서 확장 가능한 상태 관리 솔루션을 설계하고 구축하는 데 대한 약간의 의견이 있는 통찰력을 공유할 것입니다 .

접근 방식을 더 잘 설명하기 위해 몇 가지 코드 예제와 작은 프로토타입을 포함합니다.

우리는 몇 가지 다른 프로젝트에서 이 지식을 사용하여 가장 일반적인 함정 중 일부를 쉽게 피할 수 있습니다.

앱 상태 대 디자인 상태

이러한 종류의 앱에서 우리가 할 수 있는 주요 차이점 중 하나는 앱 상태와 디자인 상태입니다.

디자인 상태

예를 들어 텍스트(글꼴, 크기, 색상, 콘텐츠), 이미지, 그룹화된 요소, 연결된 요소 등 사용자가 만든 콘텐츠를 설명합니다.

디자인 상태는 디자인이 개념적으로 변경될 때마다 변경되지만 사용자가 디자인에 영향을 미치지 않는 작업을 수행할 때는 변경되지 않습니다.

디자인 상태에 영향을 미치는 작업의 몇 가지 예:

  • 요소 이동
  • 텍스트 속성 변경(색상, 크기, 글꼴)
  • 그룹 요소

디자인을 제외한 현재 앱 상태를 정의합니다. 사용자가 앱 및 메뉴와 상호 작용하면 앱 상태가 변경됩니다.

몇 가지 예:

  • 요소 선택
  • 대화상자를 열어 요소의 속성을 편집합니다.
  • 오른쪽 클릭 메뉴 표시
  • 작업 확인

각 종류의 상태에는 서로 적용되지 않는 고유한 특성이 있으며 함께 유지하면 구현이 더 복잡해집니다.

예를 들어:

  • 디자인을 저장할 때 상태의 이 부분만 저장됩니다.
  • 실행 취소/다시 실행은 설계 상태에만 적용됩니다. 앱은 디자인과 앱 상태 사이의 약간의 불일치(예: 실행 취소로 인해 선택한 요소가 더 이상 디자인에 없는 경우)에서 작동할 수 있어야 합니다.
  • 디자인을 불러올 때 디자인 상태는 단순히 디자인으로 설정하고, 앱 상태는 주로 기본값으로 초기화합니다.

앱 상태

가능할 때마다 글로벌 상태보다 로컬 상태를 선호해야 하며 앱 상태도 예외는 아닙니다.

로컬 상태를 사용할 때 코드와 그 흐름을 분석하는 것이 더 쉬워집니다. 구성 요소는 서로 명시적으로 데이터를 전달해야 하고 상호 작용이 명시적이며 수동으로 찾아야 하는 "멀리 숨겨진" 사용 효과가 없습니다.

디자인 상태

디자인 상태를 정의할 때 다음 사항을 고려해야 합니다.

  • 다음을 쉽게 구현할 수 있도록 전체 상태를 가져오고 설정할 수 있어야 합니다.
    – 디자인 로드 및 저장
    – 실행 취소/다시 실행
  • 일부만 변경되는 경우 모든 요소를 ​​렌더링하지 마십시오.

React 애플리케이션에서 실행 취소/다시 실행을 구현하는 가장 쉬운 방법 중 하나는 I mmer 를 사용하여 수정 패치를 생성하는 것입니다.

Immer는 변경 불가능한 컨텍스트(예: React 상태)에서 "변경 가능한 방식"으로 데이터 수정을 작성할 수 있게 해주는 JS 라이브러리입니다.

Immer의 또 다른 기능은 수정의 실행 및 실행 취소 패치 를 생성하는 것입니다. 이를 통해 변경 사항을 다시 실행하는 방법과 미리 보기 상태로 돌아가는 방법을 저장할 수 있습니다.

상태가 변경될 때마다 do 및 undo 패치를 저장하고 사용자가 undo/redo를 트리거할 때 사용해야 합니다.

전체 상태를 동시에 가져오고 설정해야 하는 이유는 무엇입니까?

대안은 함께 가지지 않는 것입니다. 이것은 로드 및 저장에 큰 문제가 아닌 것 같습니다. 다른 모든 상태 부분을 가져오거나 설정하기만 하면 됩니다.

하지만 undo/redo를 구현해야 할 때 문제가 됩니다. 각 상태 부분에 대해 어떤 상태 부분에 대한 것인지를 나타내는 메타데이터와 함께 생성된 패치를 저장하고 올바른 상태 부분을 수정할 수 있도록 실행 취소가 트리거될 때 읽어야 합니다.

또한 사용자 작업은 하나의 작업으로 여러 상태 부분을 수정할 수 있기 때문에 동시에 실행 취소 및 재실행할 수 있도록 동일한 작업에 속하는 패치를 추적해야 합니다.

단일 상태를 사용하면 이 모든 문제가 해결됩니다.

  • 여러 상태를 수정하는 작업이 없습니다.
  • 모든 패치는 여러 분산 상태가 아닌 상태에 적용됩니다.

이 설계 선택을 만족시키는 더 쉬운 방법은 전체 설계 상태를 같은 위치에 저장하는 것입니다. 그것은 우리에게 다음과 같은 생각 useState<DesignState>(defaultState)을 하게 할 것입니다. 아마도 당신이 짐작할 수 있듯이 이것은 우리가 "대부분의 앱을 렌더링" 고려하지 못하게 합니다.

디자인 변경 시 대부분의 앱을 렌더링하지 않음

이를 해결하기 위해 일반적으로 React의 상태 관리 라이브러리인 Recoil을 사용합니다.

반동에는 원자와 선택기 의 두 가지 주요 개념 이 있습니다.

Atoms : 와 유사한 방식으로 사용할 수 있는 상태 단위 useState이지만 전역적으로, 예를 들어

구현 으로 useState위의 코드에서 모든 DesignElement는 요소(또는 상태의 일부)가 변경될 때마다 렌더링됩니다. 이를 해결하기 위해 선택자를 사용할 수 있습니다.

선택기 : 원자 또는 다른 선택기에서 투영을 생성하는 기능. React 구성 요소가 선택기를 사용하는 경우 선택기의 결과가 변경될 때만 다시 렌더링 됩니다 (일부 주의 사항 있음).

Recoil은 또한 선택자를 정의하는 함수에서 인수를 받을 수 있도록 합니다. 이러한 유형의 선택자를 selectorFamily라고 합니다. 이것을 사용하여 elementId를 받고 요소를 제공하는 selectorFamily를 만들 수 있습니다.

요소가 수정되면 위의 코드는 일치하는 DesignElement에 대한 업데이트만 트리거하고 모든 요소 또는 디자인 구성 요소를 렌더링하지 않습니다.

세심한 관찰자는 구성 요소가 추가되거나 삭제될 때마다 디자인 구성 요소가 렌더링되어 모든 디자인 요소의 다시 렌더링을 트리거하는 것을 볼 수 있습니다. 이로 인해 특정 사용 사례에 대한 성능 문제가 발생하는 경우 DesignElement 구성 요소를 React.memo.

상태 설정

실행 취소/재실행을 단순화하기 위해 세트를 최상위 DesignState에 적용하기를 원하기 때문에 반동 콜백 을 생성 하여 수정 논리를 캡슐화하고 패치 생성을 실행 취소/재실행할 수 있습니다.

이 Codesanbox에서 최소한의 예를 찾을 수 있습니다.

폐쇄

이 블로그 게시물에서는 크리에이티브 도구의 편집기 컨텍스트에서 상태 관리를 설계할 때 주요 동인이 무엇인지, 그리고 이를 만족시키는 구현 방법을 공유했습니다.

여기까지 읽으셨다면 여러분의 의견을 알고 싶습니다. 여기 에서 저에게 연락하실 수 있습니다 .

Zeppelin Labs는 창립자와 성장하는 회사가 성장을 주도하는 차별화된 디지털 제품을 실험하고 구축하도록 돕습니다. 당신은 여기에서 우리를 찾을 수 있습니다 . 또는 여기 . 또는 여기 .

우리 팀에 합류하고 싶다면 [email protected] 로 이메일을 보내주세요.

파트너를 원하십니까? [email protected] 로 이메일을 보내주세요.

여기에서 뉴스레터 를 구독 하십시오 .