@action
setMyDetailProps(key, value) {
this._myDetail[key] = value;
}
vs
@action
setMyDetailProps(key, value) {
this._myDetail = {...this._myDetail, [key]: value};
}
- React 에서 객체의 속성 값들을 화면에 바인딩하여 출력할 때 주의점 -
상세 정보를 조회하는 페이지에서는 값을 잘 맵핑하는 것이 중요하다.
화면에 출력되는 값들이 각자 따로 관리되는 게 아니기 때문이다.
상세 정보 객체가 하나 있고 그 객체 안에 있는 여러 속성들이 화면에 바인딩되어 출력되는 구조이다.
출력하는 값들을 묶어 놓은 상세 정보 객체는 보통 store 에서 들고 있는다
view 에서는 그 store 에 있는 객체를 받아와서 그 속성 값들을 화면에 출력한다.
반대로 화면에서 수정하는 값을 store 에 있는 객체로 잘 반영하는 것도 중요하다.
view 에서 출력되는 값을 store 에서 보관 중인 객체의 값과 바인딩해 두면
화면에서 값을 수정할 때 그 내용이 이벤트를 통해서 store 객체에도 실시간으로 반영되어야 한다.
그렇지 않으면 사용자가 화면에서 값을 수정하더라도 값이 바뀌지 않을 수 있다.
그 값과 바인딩되어 있는 store 안의 값이 수정되지 않으면 화면에 출력되는 값도 바뀌지 않기 때문이다.
화면에서 출력되는 값과 실제로 store 안에 있는 값이 서로 다르거나 하는 일도 생긴다.
이때 가장 걸림돌이 되는 부분이 바로 렌더링이다.
화면에서 값을 바꿨고, 분명 store 에도 반영이 되어 있는데
결과적으로 화면에서는 엉뚱한 값이 출력되는 경우가 있다.
이런 경우는 객체 안에 해당 속성으로 초기값이 있는지 의심해 봐야 한다.
React 는 감시하고 있는 값이 바뀌면 렌더링이 새로 일어난다.
state 나 props 는 자동으로 감시하는 값들이다.
이런 값들이 바뀌면 렌더링이 다시 일어나고 새로운 값이 화면에 반영된다.
React 가 감시하는 대상들은 처음부터 값이 있는 변수들뿐이다.
그래서 객체 자체는 감시하는 대상이더라도 그 객체 안에 있는 모든 속성을 감시하는 것은 아니다.
객체 안에 처음부터 있던 속성만 감시하기 때문에
새로운 속성으로 값이 나중에 생기더라도 화면에서는 렌더링이 일어나지 않을 수 있다.
결과적으로 화면에 출력되는 값과 실제 store 값이 다르게 된다.
- 초기값이 없던 속성이 나중에 추가될 때 -
예를 들어 보자.
myDetail 이라는 상세 정보 객체가 있다.
이 객체 안에는 여러 가지 속성이 있다.
color, price, name, seq 등이 있다.
각각 값들도 초기화되어 있다.
그런데 isRecycled 라는 속성은 없었다.
이 값은 나중에 화면에서 체크하면서 값이 생긴다.
처음에는 값이 초기화되어 있지 않아서 아무 값도 없고 속성조차조 아예 존재하지 안흔다.
사용자하 화면에서 체크 박스를 클릭하면 그때 이벤트로 key 와 value 를 넘겨주고,
상세 정보 객체 myDetail 에 isRecycled 라는 key로 true 값을 새로 넣어준다.
이때 사용자가 화면에서 isRecycled 속성을 수정하여 값이 true 가 되면
이벤트 핸들러가 받아서 이 값을 store 에 있는 myDetail 객체도 반영하려고 할 것이다.
@action
setMyDetailProps(key, value) {
this._myDetail[key] = value;
}
this.store.setMyDetailProps("isRecycled", true);
사용자가 isRecycled 값을 바꾸었고, 그 값은 store 에도 반영됐다.
myDetail 값을 출력해 보니 우리가 의도했던 대로 myDetail 안에 isRecycled 값이 true 로 들어가 있다.
그럼에도 화면에 출력되는 값은 우리가 기대했던 바와는 다르다.
체크를 하거나 해제하면 이벤트 핸들러를 통해서
isRecycled 속성으로 true/false 값이 들어가기는 하지만,
화면에는 어떤 변화도 일어나지 않거나 store 값과는 다른 UI 가 출력된다.
<렌더링 기본 개념 정리 - 렌더링/렌더/커밋/가상DOM>
- React 가 감시하는 값과 렌더링 -
원인을 설명하자면 이렇다.
_myDetail 이라는 값 자체는 감시하고 있는 변수다.
_myDetail 변수 안에는 객체가 들어 있다.
이 객체 안에는 다시 여러 가지 속성과 값들이 들어 있을 것이다.
React 가 감시하는 값들은 _myDetail 변수에 객체가 할당될 때 처음부터 들고 있던 속성들뿐이다.
처음에는 없었다가 나중에 추가된 속성은 React 가 감지하지 못한다.
따라서 아예 없었다가 새로 추가된 속성은 값이 바뀌더라도 렌더링을 일으키지 못한다.
이러한 원인으로 화면에 출력되는 값과 store 에서 들고 있는 값이 다르게 되는 현상이 발생한다.
이러한 문제는 해결하려면 setProps 함수를 바꾸면 된다.
@action
setMyDetailProps(key, value) {
this._myDetail = {...this._myDetail, [key]: value};
}
this.store.setMyDetailProps("isRecycled", true);
이전에 쓰던 방법을 보면 myDetail 객체는 그대로 두고 새로운 속성만 추가했다.
this._myDetail[key] = value;
새로운 방법은 전개 연산자(Spread operator)를 사용해 아예 _myDetail 객체를 새로 할당한다.
전개 연산자를 쓰면 그 객체 안의 속성들을 복사하여 그대로 가져오고, key 이름의 속성과 값만 새로 추가한다.
두 방법의 차이는 무엇일까?
_myDetail 객체는 여러 가지 속성들을 묶어 놓은 묶음이다.
말하자면 서랍장 같은 것이다.
서랍장은 그대로 두고 안에 넣어 뒀던 여름 옷을 겨울 옷으로 바꾼다고 하면 React 는 감지하지 못한다.
그러나 서랍장 자체를 나무 서랍장에서 플라스틱 서랍장으로 새로 바꾼다고 하면 React 는 감지할 수 있다.
_myDetail 이라는 객체 안에 새로운 속성이 생기는 것은 React 가 감지하지 못하여 렌더링을 일으키지 못한다.
그러나 _myDetail 이라는 변수에 객체를 새로 할당해버리면 React 는 감시하던 변수에 변화가 생겼음을 감지하고 렌더링을 새로 한다.
상세 페이지를 조회하는 화면에서는 객체 하나를 두고 그 안에 있는 여러 속성들에 값을 바인딩하는 일이 많다.
이때 속성의 값을 수정하거나 새로운 속성 값을 추가하는 경우가 흔하다.
이러한 경우에 가장 문제가 되는 것은 렌더링이다.
이 문제를 해결하려면 속성을 수정하는 함수에 전개 연산자(Spread Operator)를 사용하면 된다.
감시 중인 변수를 아예 새로운 객체로 할당해버리면 React 에서는 변화를 감지하고 새로 렌더링한다.
230111-setProps
'React' 카테고리의 다른 글
datagrid 에 rowData 만들어서 넣어주기 - 고정 출력 행 있을 때 (0) | 2023.03.28 |
---|---|
[React] 렌더링 기본 개념 정리 - 렌더링/렌더/커밋/가상DOM (0) | 2023.02.06 |
[React.js] 클래스형 setState 안 될 때 - 덮어쓰기 되는 경우 (0) | 2023.01.23 |
[React] onChange 값이 한 박자씩 늦게 들어갈 때 / observable 변수 렌더링 뒤늦게 반영될 때 (0) | 2023.01.02 |
[React] + dataGrid 트리 구조 테이블에서 합계 구하는 법 (feat. 재귀 함수) (0) | 2022.12.12 |