Front-End/MobX

@action

Voyage_dev 2022. 12. 15. 21:40

action은 observable state를 update시키는 요인이 된다. 마치 Redux action 과도 같은 의미이다.

지금까지 observable에 proxy라고 하는 패턴을 사용해 state를 변경했다. 그러면 왜 action을 사용해야 할까?

 

이전 소스코드를 살짝 변경해 보자

 

1번째 방법

// app.js

function App() {
  const personStore = useContext(PersonContext);

  const age10 = computed(() => {
    return Math.floor(personStore.age / 10) * 10;
  }).get();
  console.log(personStore.age, personStore.name);

  const click = () => {
    // personStore.plus();
    setTimeout(
      action(() => {
        personStore.age = 45;
        personStore.name = "Kyusung";
      }),
      500
    );
  };
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          <button onClick={click}>plus</button>
        </p>
        <p>
          {personStore.age},{personStore.name}
        </p>
      </header>
    </div>
  );
}
  • 이렇게 setTimeout 함수에 콜백 함수로 aciton 함수를 넣게 되면 .5초 뒤에 값이 동시에 바뀐다.

2번째 방법

function App() {
  const personStore = useContext(PersonContext);

  const age10 = computed(() => {
    return Math.floor(personStore.age / 10) * 10;
  }).get();
  console.log(personStore.age, personStore.name);

  const click = () => {
    // personStore.plus();
    setTimeout(() => {
      runInAction(() => {
        personStore.age = 45;
        personStore.name = "Kyusung";
      });
    }, 500);
  };
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          <button onClick={click}>plus</button>
        </p>
        <p>
          {personStore.age},{personStore.name}
        </p>
      </header>
    </div>
  );
}

3번째 방법

function App() {
  const personStore = useContext(PersonContext);

  const age10 = computed(() => {
    return Math.floor(personStore.age / 10) * 10;
  }).get();
  console.log(personStore.age, personStore.name);

  const click = () => {
    setTimeout(() => {
      personStore.testAction();
    }, 500);
  };
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          <button onClick={click}>plus</button>
        </p>
        <p>
          {personStore.age},{personStore.name}
        </p>
      </header>
    </div>
  );
}

// PersonStore.js

@action
  testAction() {
    this.age = 45;
    this.name = "Kyusung";
  }
  • observable 한 것을 변경할 때는 항상 action을 달고 처리해야 한다. 물론 빼고 작성해도 정상적으로 작동은 된다.
  • 이전에는 use-strict 나 config에서 꼭 설정해야 했는데 이제는 default로 action을 강제하는 옵션이 들어있기 때문에 action을 빼고 실행하게 되면 warning만 뜬다.