- render()
render() 메서드는 클래스 컴포넌트에서 반드시 구현해야 하는 유일한 메서드입니다.
이 메서드가 호출되면 this.props 와 this.state 값을 활용하여 아래의 것 중 하나를 반환해야 합니다.
-- React 엘리먼트 : 보통 JSX를 사용하여 생성됩니다. ex) <div /> 와 <MyComponent />는 React가 DOM 노드 또는 사용자가 정의한 컴포넌트를 만들도록 지시하려는 React 엘리먼트입니다.
-- 배열과 Fragment : render()를 통하여 여러 개의 엘리먼트를 반환합니다. https://ko.reactjs.org/docs/fragments.html
-- Protal : 별도의 DOM 하위 트리에 자식 엘리먼트를 렌더링합니다. https://ko.reactjs.org/docs/portals.html
-- 문자열과 숫자 : 이 값들은 DOM 상에 텍스트 노드로서 렌더링됩니다.
-- Boolean 또는 null : 아무것도 렌더링하지 않습니다. (대부분의 경우 return test && <Child /> 패턴을 지원하는 데에 사용되며, 여기서 test는 Boolean 값입니다.
render()함수는 순수해야 합니다. 즉, 컴포넌트의 state를 변경하지 않고, 호출될 때마다 동일한 결과를 반환해야 하며, 브라우저와 직접적으로 상호작용을 하지 않습니다.
브라우저와 상호작용하는 작업이 필요하다면, 해당 작업을 ComponentDidMount() 이나 다른 생명주기 메서드 내에서 수행해야 합니다. render()를 순수하게 유지하여야 컴포넌트의 동작을 이해하기 쉽습니다.
( shouldComponentUpdate() 가 false를 반환하면 render()는 호출되지 않습니다. ) - constructor()
React 에서 Component 를 생성할 때 state 값을 초기화 하거나 메서드를 바인딩 할 때 constructor()를 사용합니다. 메서드를 바인딩하거나 state를 초기화 하는 작업이 없다면, 해당 React 컴포넌트에는 생성자를 구현하지 않아도 됩니다.
React 컴포넌트 생성자는 해당 컴포넌트가 마운트되기 전에 호출됩니다. React.Component 컴포넌트의 생성자를 구현할 때에는 다른 구문에 앞서 super(props)를 호출해야 합니다.
그렇지 않으면 this.props가 생성자 내에서 정의되지 않아 버그로 이어질 수 있습니다.
React에서 생성자는 보통 두가지 목적을 위해 사용됩니다.
-- 1. this.state에 객체를 할당하여 지역 state를 초기화
-- 2. 인스턴스에 이벤트 처리 메서드를 바인딩
constructor() 내부에서 setState()를 호출하면 안 됩니다. 컴포넌트에 지역 state가 필요하다면 생성자 내에서 this.state에 초기 state값을 할당하면 됩니다.
생성자는 this.state를 직접 할당할 수 있는 유일한 곳입니다. 그 외의 메서드에서는 this.setState()를 사용해야 합니다.constructor(props) { super(props); // 여기서 this.setState()를 호출하면 안 됩니다! this.state = { counter: 0 }; this.handleClick = this.handleClick.bind(this); }
생성자 내에서는 부수 효과를 발생시키거나 구독 작업(subscription)을 수행하면 안 됩니다.
생성자 내에서는 부수 효과를 발생시키거나 구독 작업(subscription)을 수행하면 안 됩니다. 해당 경우에는 componentDidMount() 를 대신 사용하세요. - componentDidMount()
componentDidMount() 는 컴포넌트가 마운트 된 직후, 즉 트리에 삽입된 직후에 호출됩니다. DOM 노드가 있어야 하는 초기화 작업은 이 메서드에서 이루어지면 됩니다.
외부에서 데이터를 불러와야 한다면, 네트워크 요청을 보내기 적절한 위치입니다. componentDidMount() 에서 즉시 setState()를 호출하는 경우도 있습니다. 이로 인하여 추가적인 렌더링이 발생하지만, 브라우저가 화면을 갱신하기 전에 이루어 질 것입니다.
이 경우 render()가 두 번 호출되지만, 사용자는 그 중간 과정을 볼 수 없을 것입니다.대부분의 경우, 앞의 방식을 대신하여 constructor() 메서드에 초기 state를 할당할 수 있습니다. 하지만 모달(Modal) 또는 툴팁과 같이 렌더링에 앞서 DOM의 크기나 위치를 먼저 측정해야 하는 경우 이러한 방식이 필요할 수 있습니다. 이 메서드는 데이터 구독을 설정하기 좋은 위치입니다. 데이터 구독이 이루어졌다면, componentWillUnmount()에서 구독 해제 작업을 반드시 하길 바랍니다. ( todo) - componentDidUpdate()
componentDidUpdate()는 갱신이 일어난 직후에 호출됩니다. 이 메서드는 최초 렌더링에서는 호출되지 않습니다.
컴포넌트가 갱신되었을 때 DOM을 조작하기 위하여 이 메서드를 활용하면 좋습니다. 또한, 이전과 현재의 props를 비교하여 네트워크 요청을 보내는 작업도 이 메서드에서 이루어지면 됩니다. (가령, props가 변하지 않았다면 네트워크 요청을 보낼 필요가 없습니다).
componentDidUpdate()에서 setState()를 즉시 호출할 수도 있지만, 위의 예시처럼 조건문으로 감싸지 않으면 무한 반복이 발생할 수 있다는 점에 유의해야 합니다.componentDidUpdate(prevProps) { // 전형적인 사용 사례 (props 비교를 잊지 마세요) if (this.props.userID !== prevProps.userID) { this.fetchData(this.props.userID); } }
또한 추가적인 렌더링을 유발하여, 비록 사용자는 눈치채지 못할지더라도 컴포넌트 성능에 영향을 미칠 수 있습니다.
상위에서 내려온 prop을 그대로 state에 저장하는 것은 좋지 않으며, 그 대신 prop을 직접 사용하는 것이 좋습니다. - componentWillUnmount()
componentWillUnmount()는 컴포넌트가 마운트 해제되어 제거되기 직전에 호출됩니다. 이 메서드 내에서 타이머 제거, 네트워크 요청 취소, componentDidMount() 내에서 생성된 구독 해제 등 필요한 모든 정리 작업을 수행하세요.
이제 컴포넌트는 다시 렌더링 되지 않으므로, componentWillUnmount()내에서 setState()를 호출 하면 안 됩니다. 컴포넌트 인스턴트가 마운트 해제되고, 절대로 다시 마운트 되지 않습니다.
★ constructor 메서드 안에서 super()를 호출하는 이유
자바스크립트에서 super는 부모 클래스 생성자를 가리킵니다. ( React에서는 React.Component )
super(props)가 호출되면 현재 클래스형 컴포넌트가 상속하고 있는 리액트의 Component 클래스가 지닌 생성자 함수를 호출해주는 것입니다. 따라서 super(props)를 호출하기 전까지는 constructor에서 this 키워드를 사용할 수 없습니다.
그 이유는 super()가 호출되지 않으면 this가 초기화 되지 않기 때문입니다. super(props)에서 인자로 props를 넘겨주는 것이 constructor안에서 this.props를 접근할 수 있게 만들어 주는 것입니다.
class 컴포넌트에서 state를 사용할 때에는 컴포넌트의 형태가 클래스이기 때문에 this.state로 사용할 수 있습니다. ( this.를 사용할 수 있는 이유는 위에 super()를 호출하는 이유에서 언급되었습니다. )
setState를 호출할 때마다 리액트는 state값의 변경을 감지하고 새로운 state와 함께 라이프사이클 메서드중 하나인 render 메서드를 호출합니다.
생성자 내부는 유일하게 state에 값을 직접 할당할 수 있는 공간입니다. setState는 state를 업데이트 하기 위한 메소드이고 비동기로 동작합니다. 때문에 생성자 내부에서 setState를 호출하더라도 원하는 결과를 얻을 수 없습니다.
참고자료:
react component 출처 : https://ko.reactjs.org/docs/react-component.html
'react' 카테고리의 다른 글
[React] String을 html로 파싱하기 - dangerouslySetInnerHTML (0) | 2022.02.18 |
---|---|
[Redux] Action, Reducer, Store, Dispatch, Subscribe (0) | 2022.02.14 |
[React] 리덕스 (Redux) vs Context API (1) | 2022.02.14 |
[React] super(props) (0) | 2022.01.05 |
[React] React.Component (0) | 2022.01.05 |
댓글