기록하는 개발자

<React 파헤치기-15> 컴포넌트 - 7. 컴포넌트에서의 콜백 함수 본문

Web/React

<React 파헤치기-15> 컴포넌트 - 7. 컴포넌트에서의 콜백 함수

밍맹030 2021. 12. 27. 17:49
728x90

https://mingmeng030.tistory.com/216?category=1025066 

 

<React 파헤치기-11> 컴포넌트 - 3. property

Property 상위 컴포넌트가 하위 컴포넌트에 값을 전달할 때 사용한다. property 값은 수정할 수 없다는 특징이 있다. property의 기초 App 컴포넌트는 MyComponent에 속성 형태로 프로퍼티를 전달한다. import

mingmeng030.tistory.com

앞선 위 게시물에서 상위 컴포넌트가 하위 컴포넌트에 property를 전달할 수 있음을 설명했다.
만약 하위 컴포넌트에서 전달받은 property를 변경해야 할 때는 어떻게 해야할까?

 

property의 원본을 수정할 수 있는 함수를 하위 컴포넌트에 함께 제공하면 된다.

이러한 함수를 callback 함수라고 한다. 

결과적으로 하위 컴포넌트는 전달 받은 함수를 호출할 뿐, 직접적으로 property를 변경하지는 않게 된다.

 

콜백(callback)함수

정의된 위치에서 실행되지 않고, 이후 이벤트 발생, 다른 함수의 호출 등과 같이 특정 상황에서 실행되는 함수

 

 

예제를 통해 콜백함수로 property 수정하기

import React from 'react';

class Counter extends React.Component {
    render(){
        return(
            <div>
                count : {this.state.count}
                <button onClick={this.props.onAdd()}> + </button>
            </div>
        );
    }    
}
export default Counter

 

import React from 'react';
import Counter from './Counter';

class App extends React.Component {
    constructor(props){
        super(props);
        this.state = { count : 1, };
    }
    
    increaseCount(){
        this.setState(({count}) => ({ count : count + 1 }));
    }
    
    render(){
        return(
            <Counter count={this.state.count} onAdd={this.increaseCount}/>
        );
    }    
}
export default App;

 

위와 같이 코드 실행 화면에서 + 버튼을 클릭하면 아래와 같은 오류가 발생한다.

this.setState is not a function 이라는 오류 메시지는

Counter 컴포넌트가 property로 받아온 onAdd() 함수에서 참조하는 this의 범위 때문에 발생하였다.

 

Counter 컴포넌트에서 사용한 this.props.onAdd()의 onAdd함수 내부에는 this.setState가 존재하는데,

이 this.setState는 상위 컴포넌트인 App 컴포넌트에 정의되어 있다.

그러나 this.setState가 정의되지 않은 Counter 컴포넌트에서 사용했기 때문에 해당 오류가 발생한다.

이러한 오류를 this 범위 오류라고 한다.

 

이렇게 call back 함수를 property로 전달하는 경우, 하위 컴포넌트에서 참조할 this 범위에 대한 오류를 주의해야한다.

 

bind() 함수를 통해 this 범위 오류 해결하기

방법1 - property를 전달할 때 this를 bind 해준다.

import React from 'react';
import Counter from './Counter';

class App extends React.Component {
    ...
    render(){
        return(
            <Counter count={this.state.count} onAdd={this.increaseCount.bind(this)}/>
        );
    }    
}
export default App;

방법2 - constructor 작성 시 bind를 모아두면 매번 render 호출 시마다 새로 작성하지 않아도 된다.

import React from 'react';
import Counter from './Counter';

class App extends React.Component {
    constructor(props){
        super(props);
        this.state = { count : 1, };
        this.increasCount = this.increaseCound.bind(this);
    }
    ...
    render(){
        return(
            <Counter count={this.state.count} onAdd={this.increaseCount}/>
        );
    }    
}
export default App;

수정 후 작동이 잘 되는 모습

 

단방향 흐름 방식

react는 property, state와 같은 데이터를 상위 컴포넌트에서 하위 컴포넌트 방향으로 전달한다.

데이터 변경이 필요한 경우에는 call back 함수를 호출하여 원본 데이터가 위치한 상위 컴포넌트에서 해당 데이터를 변경하고 다시 자식(하위)컴포넌트로 전달한다.

이와 같은 데이터 흐름 방식을 단방향 흐름 방식이라고 하며, 이는 원본 데이터의 무결성을 지켜준다.

 

 

+) 

react에 함수형 컴포넌트가 추가되고 hook을 사용할 수 있게 되므로써

state를 useState 함수를 통해 관리하게 되었다.

이로써 함수형 컴포넌트에서는 관리할 this가 존재하지 않기 때문에 this 범위 오류가 발생하지 않고

이에 따라 bind 함수도 사용할 필요가 없어졌다.

그러나 함수형 컴포넌트가 현재 주를 이루더라도, 과거에 클래스형 컴포넌트를 사용하여 개발한 프로젝트를 지속적으로 유지보수하는 기업들도 많기 때문에 이를 위해서라도 bind를 이해하고 넘어자.

728x90