📌 MobX 6 주요 개념
MobX 6부터는 @observable, @action, @computed 와 같은 데코레이터 문법 대신
makeObservable과 makeAutoObservable을 사용해
상태와 메서드를 명시적으로 설정하는 것이 권장됩니다.
📌 관찰 가능한 상태(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은 특정 조건이 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로 변경됨
'📌 Front End > └ React' 카테고리의 다른 글
[React] 리액트에서 Tailwind CSS 사용하기 (1) | 2024.09.20 |
---|---|
[React] 리액트에서 CSS 적용하는 여러가지 방식(Import, 인라인, CSS Module, Styled-Components) (1) | 2024.09.20 |
[React] MobX 상태 관리 라이브러리 (4) | 2024.09.11 |
[React] 리액트 동적 라우팅(Dynamic Routing) - useLocation, useNavigate, useParams, useSearchParams (1) | 2024.09.06 |
[React] 리액트 라우터 돔(React Router DOM) - BrowserRouter, Routes, Route, Outlet, Link, NavLink (0) | 2024.09.04 |