https://programmingwithmosh.com/react/build-a-react-calendar-component-from-scratch/
Class Component로 작성된 Calendar 코드를 React Hooks 형태로 리팩토링하는 중 이전 달, 다음 달 화살표 버튼을 누르면 상태값이 바뀐 후 자동으로 리렌더링이 될 것을 기대 했다.
class Calendar extends React.Component {
state = {
dateObject: moment(),
};
onPrev = () => {
this.setState({
dateObject: this.state.dateObject.subtract(1, "month")
});
};
onNext = () => {
this.setState({
dateObject: this.state.dateObject.add(1, "month")
});
};
하지만 위 코드를 아래처럼 React Hooks 형태로 처음 바꿨을 때 State값은 바뀌지만 리렌더링이 되지 않는 다는 것을 발견.
function Calendar (){
const [dateObject, setDateObject] = setState(moment());
const onPrev = () => {
let result = dateObject.subtract(1,"month")
setDateObject(result);
};
const onNext = () => {
let result = dateObject.add(1,"month")
setDateObject(result);
};
원인은 간단했다. 리렌더링이 안되는 이유는 React LifeCycle이 작동하지 않는 다는 것이고 LifeCycle이 작동하지 않는 이유는 state값을 immutable하게 바꾸지 않았기 때문이었다.
const onPrev = () => {
let result = dateObject.clone().subtract(1,"month")
setDateObject(result);
};
moment 라이브러리를 사용해서 moment()를 초기 상태값으로 지정했던 dateObject를 직접 조작하는 dateObject.subtract 는 mutable한 메소드라는 것을 알았고 immutable하게 바꾸기 위해 clone() 메소드를 사용했더니 정상적으로 리렌더링이 됨을 알 수 있었다.
앞으로 class component를 function component로 바꿀 때 state 변경할 시 이 부분을 더욱 주의해야 겠다.