[React] 생명주기 - ComponentDidUpdate

예리에르·2021년 12월 13일
1

React

목록 보기
12/17
post-thumbnail

컴포넌트 생명주기

  • 마운트
  • 업데이트
  • 마운트 해제
    세 가지를 거쳐 나타난다.

componentDidMount()

  • componentDidMount() 는 컴포넌트가 마운트 된 직후 호출된다. 초기화 작업은 이 메서드에 이루어지며 된다.
    API요청을 통해 외부에서 데이터를 가져와야 한다면, 요청을 보내기에 적절한 위치이다.

componentDidUPdate()

componentDidUpdate(prevProps, prevState, snapshot)
  • 데이터가 갱신이 일어난 직수 호출된다. 그래서 처음 렌더링 될때는 호출되지 않는다. 이전의 props와 현재의 props를 비교하기 때문에 특정 props 변화에 따라 네티요청을 보내는 메서드에 이루어지면 좋다.

주의할 점

  • componentDidUpdate() 에서 setState()를 호출해도 되지만, 조건문을 감싸주지 않으면 무한루프가 발생할 수 있다. break와 같은역할을 가진 조건문을 걸어줘야한다. 즉, 실제 변경이 일어난 경우만 작동하도록 코드를 작성해야한다.

사용예시 (체크박스)

적용계기

  • 팀의 디자인시스템 개발중 Checkbox를 개발하고있었다. 기존 단일 체크박스와 그룹 체크박스를 구성하는데 기존의 코드를 구현할 수 있었다.
  • 그런데!! 생각지도 못한 전체체크에서 문제가 발생했다. 기존의 체크박스 그룹 하나만으로 해결이 불가능했고, 전체체크 한다는 이벤트(경우)를 인식해 당일체크박스의 값을 전달바다 체크박스 그룹을 컨트롤 해야했다.
  • 체크박스그룹은 그룹 안 각각의 체크박스 체크인식 뿐 아니라 전체체크도 인식해야했다. 두가지의 체크를 인식하고 구분하기 위해 여러방법을 생각하다 특정 props의 값이 갱신되면 업데이트해야겠다 생각하였고 componentDidUpdate 적용을 하였다.

적용코드

props중 values를 중점으로 봐주세요.

  • DoucumentCheckbox.tsx
// Checkbox로 내려줄 체크된 리스트
@action
    private onChangeAllCheck = () => {
        this.isAll = !this.isAll;
        if (this.isAll) {
            this.AllCheckedList = [...allList];
        } else {
            this.AllCheckedList = [];
        }
        console.log(toJS(this.AllCheckedList))
    }
...
<div>
  <p>그룹 (Group) 정렬 - 전체선택</p>
  // 단일체크박스
  <Checkbox onChange={this.onChangeAllCheck} >전체선택</Checkbox>
  // 체크박스 그룹
  <CheckboxGroup options={options} onGroupChanged={action((values: any[]) => {
                                                   this.AllCheckedList = [...values];})}
                                                   values={this.AllCheckedList}/>
</div>
  • CheckboxGroup.tsx
  componentDidMount() {
        const {defaultValue, values} = this.props;
        if (defaultValue) {
            this.checkedList = [...defaultValue];
        } else if (values) {
            this.checkedList = [...values];
        }
    }

    componentDidUpdate(prevProps: Readonly<CheckboxGroupInnerProps>, prevState: Readonly<{}>, snapshot?: any): void {
        if (prevProps.values !== this.props.values) {
            const {values = []} = this.props;
            this.checkedList = [...values];
        }
    }
  • 여기서 values는 전체체크 체크박스를 데이터를 담고있는 배열이다. componentDidMount() 때 만약 사용자가 기본으로 체크한 데이터가 있다면 checkedList에 넣어준다.

  • 그런 후 개별의 체크박스가 클릭되고 변경된 checkedList가 부모로 올라가게된다. onChangeAllCheck 로 AllCheckeList가 변경되면서 props 데이터가 변경된다.

  • 이 변화는 componentDidUdpate에서 감지하여 이전 props와 현재 props를 비교하여 변경된 데이터를 checkedList에 담아준다.

  • Mount된 후 작동된 컴포넌트 핸들링을 통일성있게 유지할 수 있게 된다.
    +) 그냥 checkbox도 componentDidUpdate를 통해 체크된지 안된지 여부를 통일해서 나타낼 수 있다.

// 2. 체크박스 그룹의 변경에따라 자식인 체크박스의 체크여부 통일 가능
    componentDidUpdate(prevProps: Readonly<CheckboxProps>, prevState: Readonly<{}>, snapshot?: any): void {
        if (this.props.checked != undefined &&
            prevProps.checked !== this.props.checked) {
            this.isChecked = this.props.checked;
        }
    }
...
// 1. 체크여부를 판단하고 컨트롤하는 기본 함수
    @action
    private handleCheckedBox = (e: React.MouseEvent<HTMLLabelElement>) => {
        const {onChange, disabled, checked, value} = this.props;
        const targetValue = (e.target as HTMLLabelElement).textContent || value || '';

        if (!disabled) {
            if (checked) {
                this.isChecked = true;
            }
            this.isChecked = !this.isChecked;

            onChange && onChange(targetValue, this.isChecked);
        }
    }

class 컴포넌트를 사용하면서 React에서 제공하는 lifecycle을 사용할 수 있는 장점이 있지만 함수형 컴포넌트로 변화를 이끄는 React 흐름에 따라 hook의 useEffect와 같은 기능을 사용하는 방법의 학습을 추가로 병행해야겠다고 생각한다.

profile
비전공 프론트엔드 개발자의 개발일기😈 ✍️

0개의 댓글