본문 바로가기
📌 Front End/└ React

[React] MobX 상태 관리, 비동기 작업, 이벤트 시스템(action, computed, runInAction, autorun, reaction, when)

by 쫄리_ 2024. 9. 13.
728x90
반응형

📌 MobX 6 주요 개념

MobX 6부터는 @observable, @action, @computed 와 같은 데코레이터 문법 대신

makeObservablemakeAutoObservable을 사용해

상태와 메서드를 명시적으로 설정하는 것이 권장됩니다.


📌 관찰 가능한 상태(Observable) / 상태 변경 메서드(Action)

  • Observable
    상태가 바뀌면 자동으로 감지하고, 이를 사용하는 컴포넌트를 자동으로 업데이트

  • Action
    상태를 변경하는 메서드, 여러 변경을 그룹화하여 성능 개선

  • makeAutoObservable
    클래스의 생성자에서 호출하면 모든 속성과 메서드를 
    자동으로 observable 및 @action으로 설정

  • makeObservable
    클래스의 속성을 observable로 만들고 
    메서드를 @action으로 명시적으로 설정

import { makeAutoObservable } from 'mobx';

class Store {
  value = 0;  // 관찰 가능한 상태

  constructor() {
    // ▶ 모든 속성과 메서드를 자동으로 observable 및 @action으로 설정
    makeAutoObservable(this);  
  }

  increment() {
    this.value += 1;  // 상태를 변경하는 액션 메서드
  }
}

const store = new Store();
store.increment();  // value가 1로 변경됨 (화면 업데이트)

 


📌 계산된 값 캐싱 (Computed)

Computed기존 상태로부터 계산된 값을 의미하며,

상태가 변경되지 않으면 캐싱된 값을 반환하여 불필요한 계산을 방지합니다.

메서드명 앞에 get 키워드를 붙이면 자동으로 computed 값이 됩니다.

 

📝 Computed 형태

// ▶ 정의
get 메서드명() {
  // 상태가 변경되면 계산된 값을 새로 계산
  // 상태가 변경되지 않으면 이전에 계산된 값을 재사용
  return 상태변경확인할매개변수명;  // 계산된 값을 반환
}

// ▶ 사용
스토어클래스명.메서드명;  // 메서드를 변수처럼 사용하여 계산된 값을 가져옴

사용예시

import { makeAutoObservable } from 'mobx';

class Store {
  value = 2;  // 관찰 가능한 상태

  constructor() {
    makeAutoObservable(this); // 클래스의 속성과 메서드를 자동으로 observable로 설정
  }
  
  // ▶ computed 정의
  get doubleValue() {
    // 메서드명 앞에 'get' 키워드를 붙이면, 자동으로 computed 값이 됨
    // 상태가 변경되지 않으면 캐싱된 값을 반환하여 성능을 최적화
    return this.value * 2;  // computed 값 (자동으로 캐싱됨)
  }
}

const store = new Store();
// ▶ 메서드를 함수호출() 방식이 아닌 .변수처럼 사용
console.log(store.doubleValue);  // 4가 출력됨(상태가 변경되지 않아 캐싱된 값이 사용됨)

 


📌 비동기 작업 후 상태 변경 (runInAction)

runInAction 비동기 작업과 직접적으로 관련된 함수가 아니지만,

비동기 작업이 끝난 후 상태 변경을 안전하게 묶어서 처리할 때 유용합니다.

비동기 작업 중 상태를 변경하지 않고,

비동기 작업이 완료된 후에만 상태를 변경하고 싶을 때 runInAction을 사용하면 적합합니다.

MobX는 상태 변경을 하나의 액션으로 묶어 추적하고,
일관성 있게 상태를 관리할 수 있습니다.

 

📝 runInAction 함수 형태

runInAction(() => {
  // 비동기 작업이 끝난 후 상태를 변경하는 코드
});

사용예시

import { makeAutoObservable, runInAction } from 'mobx'; 

class Store {
  value = 0;  // 초기 상태 값

  constructor() {
    makeAutoObservable(this);  // 상태를 자동으로 관찰 가능
  }

  // ▶ 비동기 작업을 처리하는 메서드
  async fetchData() {
    // ● 비동기 방식으로 데이터 가져옴
    const response = await fetch("/api/data");
    const data = await response.json();  // 서버에서 받은 데이터를 JSON 형태로 변환

    // ● 비동기 작업이 끝난 후 상태를 안전하게 업데이트
    runInAction(() => {
      this.value = data.length;  // 가져온 데이터의 길이를 상태에 저장
    });
  }
}

const store = new Store();  // Store의 인스턴스 생성
store.fetchData();  // 비동기 데이터 요청을 시작

 


📌 MobX 이벤트 시스템

MobX의 이벤트 시스템은 상태 변경에 따라 자동으로 특정 동작을 실행합니다.

이를 통해 상태 변화에 자동으로 반응하여 작업을 수행할 수 있습니다.

일반적으로 스토어의 생성자나 초기화 코드에서 설정하여 상태 변화를 추적하고 필요한 동작을 자동으로 수행합니다.

 

  • autorun : 상태 변경 시 자동으로 실행되는 함수 설정
  • reaction : 특정 상태 변경 시 콜백 함수 실행
  • when : 특정 조건이 만족될 때 한 번만 실행

🔎 Observable 값 상태 변경 시 자동 실행 (autorun)

autorun 상태가 변경될 때마다 자동으로 실행되는 함수를 정의하는 데 사용합니다.

이를 통해 상태가 변경될 때 특정 작업을 자동으로 수행할 수 있습니다.

 

📝 autorun 함수 형태

autorun(() => {
  // 스토어 클래스에 정의된 모든 관찰 가능한 값 중 하나라도 변경될 때
  // 이 콜백 함수가 자동으로 실행
});

사용예시

import { makeAutoObservable, autorun } from 'mobx';

class Store {
  value = 2;  // 관찰 가능한 상태

  constructor() {
    makeAutoObservable(this);
    
    // ▶ autorun 함수 정의
    autorun(() => {
      // ● 상태값이 변경될 때마다 실행되는 콜백 함수
      console.log("Value changed: ", this.value);  
    });
  }

  increment() {
    this.value += 1;  // 상태를 변경하는 액션 메서드
  }
}

const store = new Store();
// ▶ 값이 변경되면서 autorun함수의 콜백함수 자동실행
store.increment();  // value가 3으로 변경됨, 콘솔에 "Value changed: 3" 출력

 


🔎 상태 값 변경 시 콜백 함수 실행 (reaction)

reaction 특정 observable 값이 변경될 때만 실행되는 콜백 함수를 정의합니다.

이 함수는 두 개의 매개변수를 받아, 현재 값과 이전 값을 비교할 수 있습니다.

 

  • 첫 번째 매개변수 : 관찰할 상태 값
  • 두 번째 매개변수 : 값이 변경될 때 실행될 콜백 함수 (현재 값, 이전 값 - 매개변수로 전달)

 

📝 reaction 함수 형태

reaction(
  () => /* 스토어 클래스에 정의된 값 변경을 체크할 매개변수명 */,
  (현재값, 이전값) => {
    // ▶ 값이 변경될 때 실행되는 콜백 함수
    //    현재값 : 현재 상태 값
    //    이전값 : 이전 상태 값
  }
);

사용예시

import { makeAutoObservable, reaction } from 'mobx';

class Store {
  value = 2;  // 관찰 가능한 상태

  constructor() {
    makeAutoObservable(this);

    // ▶ reaction 함수 정의
    reaction(
      // ● 관찰할 상태 값
      () => this.value,  
      (currentValue, previousValue) => {
         // ● 상태 값이 변경될 때마다 실행되는 콜백 함수
         console.log(`Value changed from ${previousValue} to ${currentValue}`);
      }
    );
  }

  increment() {
    this.value += 1;  // 상태를 변경하는 액션 메서드
  }
}

const store = new Store();
// ▶ 값이 변경되면서 reaction함수의 콜백함수 자동실행 (현재값, 이전값 출력)
store.increment();  // value가 3으로 변경됨

 


➕ 단순 값 변경 감지 (상태 값의 직접적인 변화)

  • reaction은 this.number의 값을 관찰합니다.
  • this.number의 값이 변경되면, 콜백 함수가 자동으로 실행됩니다.
  • 예를 들어, this.number가 3에서 4로 변경되면, 콜백 함수가 실행됩니다.
reaction(() => this.number, (currentValue, previousValue) => {
  // 상태 값이 변경될 때마다 실행되는 콜백 함수
});

 

 

연산된 값의 변경 감지 (상태 값 이용한 계산 결과 변화 감지)

  • this.number % 2 === 0이라는 표현식을 관찰합니다.
  • 즉, this.number가 짝수인지 홀수인지에 따라 결과가 true 또는 false로 바뀝니다.
  • this.number가 3에서 4로 변경되면, 
    this.number % 2 === 0의 결과가 false에서 true로 바뀌므로, 콜백 함수가 실행됩니다.
reaction(() => this.number % 2 === 0, (currentValue, previousValue) => {
  // 연산된 값이 변경될 때마다 실행되는 콜백 함수
});

 


🔎 조건 만족 시 단일 실행 (when)

when 특정 조건이 true가 될 때까지 기다렸다가,

조건이 만족되면 한 번만 실행되는 함수를 정의할 때 사용됩니다.

 

  • 첫 번째 매개변수 : 조건식 (조건이 true가 될 때까지 대기)
  • 두 번째 매개변수 : 조건이 충족될 때 실행할 작업 (조건이 만족되면 한 번만 실행)

 

📝 when 함수 형태

when(
  () => /* 조건식 */,  // 조건이 true가 될 때까지 대기
  () => {
    // 조건이 충족되면 실행되는 콜백 함수
  }
);

사용예시

import { makeAutoObservable, when } from 'mobx';

class Store {
  value = 10;  // 관찰 가능한 상태

  constructor() {
    makeAutoObservable(this);

    // ▶ when 함수 정의
    when(
      () => this.value > 10,  // 조건이 true가 될 때까지 대기
      () => console.log("Value exceeded 10!")  // 조건이 충족되면 실행
    );
  }

  increment() {
    this.value = 11;  // 상태를 변경하는 액션 메서드
  }
}

const store = new Store();
// ▶ 값이 변경되면서 조건이 만족하여, when함수의 콜백함수 한 번만 실행
store.increment();  // value가 11로 변경됨

 


when과 비동기 작업의 관계

  • 조건 기반 실행
    • when은 특정 조건이 true가 될 때까지 기다립니다. 
      조건이 충족되면 한 번만 지정된 콜백 함수를 실행합니다. 
      이 때 콜백 함수에서 비동기 작업을 수행할 수 있습니다.
  • 비동기 작업의 실행 타이밍 조절
    • 비동기 작업이 필요한 경우, 
      when을 사용하여 비동기 작업이 실행될 타이밍을 조건에 따라 조절할 수 있습니다. 
      즉, 비동기 작업이 조건이 충족될 때만 실행되도록 보장할 수 있습니다.
when(() => 1 == 2, () => {
  // 이 콜백 함수는 조건이 true가 될 때 실행됩니다.
  // 여기서 비동기 작업을 수행할 수 있습니다.
  // 예를 들어, 서버에서 데이터를 가져오는 작업 등을 실행할 수 있습니다.
});

 

 

사용예시

import { makeAutoObservable, when } from 'mobx';

class Store {
  value = 10;  // 관찰 가능한 상태

  constructor() {
    makeAutoObservable(this);

    // ▶ 조건이 true가 되면 비동기 작업 실행
    when(
      () => this.value > 10,  // 조건
      () => {
        // 비동기 작업: 서버에서 데이터 가져오기
        fetch('/api/data')
          .then(response => response.json())
          .then(data => {
            console.log(data);  // 데이터 출력
          });
      }
    );
  }

  increment() {
    this.value += 1;  // 상태를 변경하는 메서드
  }
}

const store = new Store();
// ▶ 값이 변경되면서 조건이 만족되어 비동기 작업 실행
store.increment();  // value가 11로 변경됨

 


728x90
반응형