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