Side-effect-only Vuex Mutation / Action

Vuex의 Mutation과 Action에서는 오직 Side-effect(부수효과)만이 있는 코드를 작성하는 것이 좋다. Side-effect-only라는 단어를 좀 더 자세히 설명해보자. 이는 부수효과가 있어도 된다는 뜻이 아니라, 부수효과만 있어야 한다는 의미이며, 가능한 한 return statement를 쓰지 말아야 한다는 주장이다.

결론: Vuex의 Mutation / Action (이하 M/A)의 기본 설계 철학에서 이미 Side-effect를 종용한다.

Mutation은 state를 첫 번째 인자로부터 destructuring으로 가져와 조작한다. 이미 Mutation에서 일어나는 모든 행위는 인자로 받은 state를 변화시키는 행위일 뿐이다. Action은 (거의 대부분) 비동기적인 호출이 들어가는 코드를 await 한 뒤에 결과를 하나의 또는 여러 개의 Mutation의 commit으로 state를 조작하는 방식이다.

따라서, 모든 M/A의 호출은 (원칙적으로) 파라미터로 받은 state를 변화시키는 것이 목적이기 때문에 특정 결과값을 리턴하기 보다는 그 값까지 state에 넣거나, 혹은 그것이 이상하다고 느껴진다면 전체 로직을 vuex로 부터 분리하는 것이 맞다. 하지만, Action의 경우 state를 변화시키지 않아도 된다(= Mutation을 commit하지 않아도 된다)고 생각하는데, 이 주장에는 설명이 더 필요하다.


 

내 생각에 state를 변화시키지 않는 Mutation은 의미가 없다.

또한, 첫 번째 인자로부터 destructuring한 state / getters / commit를 하나라도 사용하지 않는 Action 또한 의미가 없다. (즉, commit을 하지 않는 Action이 존재해도 된다.)

이 두 가지 원칙에 위배되는 M/A는 Vuex에서 빠지는 것이 맞다. (그 예로, 회원가입 할 때 유저가 입력한 이메일이 이미 가입된 이메일인지 체크하는 것은 Vuex의 action에 있을 이유가 전혀 없다… input의 validation을 vuex state에 올려놓지 않은 이상)

하지만 Mutation을 commit하지 않는 Action

을 허용한다니? 그런 함수들을 Vuex.action에 정의하지 않는다면 두 가지 문제가 발생한다.

  1. 그런 함수에게 파라미터를 전달하기 위해 state나 getters로 가져와야 한다. 이는 쓸 데 없이 코드량을 늘리는 매우 쉬운 방법이다.
  2. 서버로부터 비동기호출을 이용해 받아온 정보를 state에 넣어주는 로직은 Vuex.actions에 들어가겠지만, 클라이언트로부터 발생한 정보를 비동기호출로 서버에 보내는 로직은 다른 곳에 작성되어야 한다. series of concern? 이거.. 뭐 그거..

Leave a Reply