만족

[React] MobX 함수형으로 사용해보기 본문

[React] MobX 함수형으로 사용해보기

FrontEnd/React Satisfaction 2021. 8. 18. 01:36

지난 포스트(MobX 실제로 사용해보기)에서 상태를 클래스 형태로 사용했었다.

 

class Timer {
    secondsPassed = 0

    constructor() {
        makeAutoObservable(this)
    }

    increaseTimer() {
        this.secondsPassed += 1
    }
}

const myTimer = new Timer()

 

함수형 컴포넌트만 사용하는 사람들 입장에서는 별로 보기 좋은 모양새가 아니다.

 

const timer = observable({
  secondsPassed: 0
});

const increaseTimer= ()=>{
	timer.secondsPassed+= 1;
}

export default {
  secondsPassed: timer.secondsPassed,
  increaseTimer
};

위 타이머 컴포넌트를 다음과 같이 바꿔 쓸 수 있다.

 

js 클래스에 대한 이해가 없더라도 손쉽게 알아볼 수 있다.

 

사용

import myTimer from 'path/to/timer';

const TimerView = observer(() => 
  <div onClick={myTimer.increaseTimer}>
    <span>Seconds passed: {myTimer.secondsPassed}</span>
  </div>
);

// Pass myTimer as a prop.
ReactDOM.render(<TimerView/>, document.body)

사용방법은 동일하다.

 

사이드이펙트 발생시키기

mobx에 의해 관리되는 상태가 변경될 때 특정 동작을 할 수도 있다.

 

const timer = observable({
  secondsPassed: 0
});

const increaseTimer= ()=>{
	timer.secondPassed+= 1;
}

//autorun에 전달된 함수는 timer의 상태가 바뀔 때마다 호출된다
autorun(()=>{
  console.log('current Timer value', timer.secondsPassed);
})

export default {
  secondsPassed: timer.secondsPassed,
  increaseTimer
};

autorun이라는 함수를 이용한다.

 

만약 autorun을 중지시키고 싶다면, disposer를 사용한다.

 

const timer = observable({
  secondsPassed: 0
});

const increaseTimer= ()=>{
	timer.secondPassed+= 1;
}

//autorun에 전달된 함수는 timer의 상태가 바뀔 때마다 호출된다
//autorun이 반환하는 disposer를 사용하면 autorun을 비활성화할 수 있다.
const disposer= autorun(()=>{
  console.log('current Timer value', timer.secondsPassed);
});


timer.increaseTimer();
//current Timer value 1 출력됨

//autorun을 중지시킨다
disposer();

timer.increaseTimer();
//아무것도 출력되지 않음

export default {
  secondsPassed: timer.secondsPassed,
  increaseTimer
};

 

선택적으로 사이드 이펙트 발생시키기

 

const timer = observable({
  secondsPassed: 0
});

const increaseTimer= ()=>{
	timer.secondPassed+= 1;
}

//autorun에 전달된 함수는 timer의 상태가 바뀔 때마다 호출된다
autorun(()=>{
  console.log('current Timer value', timer.secondsPassed);
});

//첫 번째는 사이드이펙트 발동 조건을 리턴하는 함수를
//두 번째는 첫 번째에서 true를 반환했을 때 발생시킬 사이드이펙트를 전달한다
when(()=> timer.secondsPassed%2 === 0, ()=> console.log('timer value is even!'));

export default {
  secondsPassed: timer.secondsPassed,
  increaseTimer
};

when을 사용해볼 수 있다.

 

이렇게 하면 timer.secondsPassed가 짝수일 때만

timer value is even! 이 출력된다.

 



Comments