(21.09.07) Moment.js의 moment는 mutable하다
도깨비젤리
·2021. 9. 7. 23:03
작은 지식이라도, 하루에 하나씩.
한 줄 요약
🦄Moment.js의 method들은 원본 객체를 훼손시킨다.(moment 객체들이 mutable하다.)🦄
* mutable과 immutable에 대해서 궁금하다면 여기로 ⬇
본문
글을 시작하기 앞서, 본인의 은사님이 알려주신 지식을 공유하겠습니다.
moment 객체가 mutable 하기 때문에 사용하지 말라는 말씀을 하셨는데, 이 글을 볼 당시만 해도 나는 moment.js를 써본 적이 없기에 "아 그렇구나~"하고만 있었다.
근데 참 사람 일이라는게 기구하다. 회사에서는 moment.js를 핵심 라이브러리로 쓰고 있으니까 말이다.
그래서 moment.js를 어찌어찌 배워서 쓰고 있었는데, (아쉽게도 moment.js의 단점을 개발팀한테 피력할 기회는 가지지 못했다😁😁😁) 오늘 큰 사건이 하나 터졌다.
나는 지금 회사에서 월별로 정리된 데이터들을 화면에 출력하고, ant-design의 datepicker를 변경하면 mobx로 관리하는 currentMonth라는 moment 객체가 바뀌면서 새로운 데이터가 화면에 랜더링 되는 페이지를 만들고 있다.
근데 엥?? datepicker로 currentMonth를 바꾸니까, 찍은 날짜에서 -2月가 된 날짜가 선택되는 것이다!!
21/09 선택 --> 화면에는 21/07 출력
아주 미치고 팔짝 뛸 노릇이였다. mobx 개발자 도구도 켜보고, 콘솔 창도 켜서 이리 찍고 저리 찍고 몇 시간 동안 삽질을 한 결과, render 이전에는 정상적으로 currentMonth가 설정되다가, render 단계에서 갑자기 날짜가 -1月씩 변하는 것을 확인할 수 있었다!!
render 부를 좀 더 자세히 뜯어본 결과. 범인을 찾을 수 있었다. 범인은 바로, currentMonth 이전 달을 표시하기 위해 변수화 했던 currentMonth.subtract(1,"months")였다.
render(){
//...전략
const {currentMonth} = this.blurblurStore // moment.Moment
const lastMonth = currentMonth.subtract(1,'months') //여기서 currentMonth가 변형된다
//...후략
}
최초 랜더시에는 currentMonth가 정상적인 값을 가지고 있었으나, 랜더부가 실행됨과 동시에 currentMonth.subtract(1,'months')가 실행되어 currentMonth의 값을 바꾸게 된것이다. 자세한 연유는 모르지만, 컴포넌트를 불러오면서 render가 한번 더 실행되면서 또 한번 currentMonth.subtract(1,'months')가 실행되면서 화면에 보여지는 currentMonth는 실제 값보다 -2月이 된 값이 된것이다.
범인을 알았으니, 이제 체포만 하면 되겠다.
원본만 바꾸지 않으면 되므로, 원본과 동일한 값을 가진 moment 인스턴스를 생성하여 조작하면 되겠다.
render(){
//...전략
const {currentMonth} = this.blurblurStore // moment.Moment
const lastMonth = moment(currentMonth).subtract(1,'months') //여기서 currentMonth가 변형된다
//...후략
}
moment를 call할 때 params로 moment 객체 자체를 받을 수도 있는데, 이렇게 하면 params와 같은 값을 가진 새로운 moment 객체를 만들어준다.
currentMonth는 mobx에 의해 관측되고 있고, 매 랜더마다 새로 할당되기 때문에, currentMonth가 바뀔 때마다 lastMonth도 currentMonth에 맞는 value를 가지게 된다.
해결하고 보니 엄청 사소한 문제인데, 이거 잡을라고 쓴 시간이 너무 길었다.
그래도 해결한게 어디냐만은....시간이 너무 아깝다는 생각이 드는 건 어쩔 수 없나보다. 계속해서 정진해야겠다
'TIL' 카테고리의 다른 글
(21.09.14) 끝내주는 css 속성들 (0) | 2021.09.14 |
---|---|
(21.09.09) 상태관리에 관하여 (feat. react.state && mobx) (0) | 2021.09.09 |
(21.09.07)React fast-reload (0) | 2021.09.07 |
(21.09.05) Promise에 관하여 (0) | 2021.09.06 |
(21.09.05) ParseInt vs Number (0) | 2021.09.05 |