본문 바로가기

Front-End/React

[React] 220423 학습일기

http://www.yes24.com/product/goods/97782392

 

초보자를 위한 리액트 200제 (React) - YES24

따라하면서 이해하는 React A to Z리액트를 시작하기 전에 개발 환경을 준비하는 과정부터 시작하여 예제 파일을 실행하는 방법을 안내한다. 입문부터 초급, 중급, 활용, 실무까지 5개의 파트로 나

www.yes24.com

 

1. 생명주기 함수 static getDerivedStateFormProps(props, state) 사용하기

 

App.js를 수정해보자.

import React from 'react';
import './App.css';
import R006_LifecycleEx from './R006_LifecycleEx';


function App() {
  return (
    <div>
      <h1>Start React 200!</h1>
      <p>CSS 적용하기</p>
      <R006_LifecycleEx
        prop_value = 'FromApp.js'
      />  
    </div>
  );
}

export default App;

R006_LifecycleEx.js라는 파일을 아직 만들기 전이지만 R006_LifecycleEx.js안의 R006_LifecycleEx 컴포넌트로 prop_value라는 변수를 전달한다.

이렇게 어떤 컴포넌트로 변수를 전달할 때에는 저렇게 변수명과 값을 써주고 닫는 태그 없이 /> Self-closing tag를 써줘도 되는 것 같다.

 

R006_LifecycleEx.js 라는 파일을 만들고 아래의 코드를 넣자.

import React, {Component} from "react";

class R006_LifecycleEx extends Component {
    static getDerivedStateFromProps(props, state) {
        console.log('2. getDerivedStateFromProps Call :'+props.prop_value);
        return {};
    }

    constructor(props) {
        super(props);
        this.state = {};
        console.log('1. constructor Call');
    }

    render(){
        console.log('3. render Call');
        return (
            <h2>[THIS IS CONSTURCTOR FUNCTION]</h2>
        )
    }
}

export default R006_LifecycleEx;

ES7+ React/Redux/React-Native snippets 익스텐션을 쓰는데도 getDerivedStateFormProps(props, state) 이 함수는 자동완성에 안 뜬다.. 그래서 방법을 찾아보다가 아래의 링크를 통해 Reactjs code snippets 익스텐션을 깔면 이니셜만 입력해줘도 getDerivedStateFormProps(props, state) 이 함수가 뜬다는 것을 알게되었다.

https://choiguevara88.tistory.com/7

 

React Tip. Visual Studio Code 리액트 문법 자동완성 플러그인 Reactjs code snippets

VS Code에는 신규로 컴포넌트를 정의할 때마다 일일이 코드를 작성해야 하는 번거로움을 줄여주는 고마운 플러그인이 있다. 좌측 추가 플러그인 설치탭을 클릭한 뒤 reactjs 라고 입력 후 검색하면

choiguevara88.tistory.com

 

위의 코드를 살펴보자면

 

  • getDerivedStateFromProps(props, state) 함수:
    • constructor() 함수 다음으로 실행됨
    • 컴포넌트가 새로운 props를 받게 되었을 때 state를 변경해줌.
  • App.js에서 전달한 prop_value라는 변수를 props.prop_value로 접근해 가져올 수 있다.

App.js에서

<R006_LifecycleEx
        prop_value = 'FromApp.js'
      />

코드를 통해 prop_value를 전달했다

prop_value는 R006_LifecycleEx 모듈의 props이기 때문에

 

아래의 코드를 통해

static getDerivedStateFromProps(props, state) {
        console.log('2. getDerivedStateFromProps Call :'+props.prop_value);
        return {};
    }

R006_LifecycleEx.js에서 props를 넘겨받으면 props.prop_value를 통해 전달받은 prop_value에 접근할 수 있다.

 

실행된 페이지의

콘솔창을 확인해보면

constructor 함수가 가장 먼저 실행되고

getDerivedStateFromProps(props, state) 함수가 실행된 후

render 함수가 실행되는 것을 알 수 있다.

 

 

2.

self- closing tag 에 대해서 찾아봤다.


Q. 자바스크립트에서 />를 뭐라고 해?

A.

자바스크립트에서 /> Self-closing tag로서, 해당 태그가 닫히지 않아도 되는 태그를 나타냅니다. 이러한 태그는 XML XHTML에서 자주 사용됩니다. 예를 들어 <img> 태그는 <img /> 작성할 있습니다. 이러한 Self-closing 태그는 XHTML 문서에서 반드시 작성되어야 하지만, HTML 문서에서는 작성하지 않아도 됩니다


Q. 그냥 닫는태그 없이 무조건 다 /> 써줄 수 있는 거야?

A.

아니요, 그렇지 않습니다. Self-closing 태그는 일부 태그에서만 사용할 수 있습니다. 예를 들어, <img>, <link>, <input>, <br>과 같은 태그는 Self-closing 태그로 작성할 수 있지만, <div>, <p>, <table>과 같은 태그는 Self-closing 태그로 작성할 수 없습니다. 이러한 태그들은 닫는 태그가 필요합니다.

또한, 이러한 Self-closing 태그를 사용할 때에도 문법적으로 정확하게 작성해야 합니다. 예를 들어, <img> 태그를 Self-closing 태그로 작성할 때에는 <img /> 같이 공백이 포함되어야 합니다. 공백이 포함되지 않은 경우 문법 오류가 발생할 있습니다.

 


Q. react도 xhtml 문서야?

A.

React는 라이브러리이며, 마크업 언어가 아닙니다. React를 사용하여 생성된 웹 페이지는 HTML 또는 XHTML 문서일 수 있습니다.

React를 사용하여 웹 페이지를 개발할 때, 일반적으로 JSX라는 문법을 사용하여 UI를 구성합니다. JSX는 JavaScript 확장 문법으로, XML과 비슷한 형태의 마크업을 작성할 수 있습니다. JSX 코드는 React에서 컴파일되어 일반적인 JavaScript 코드로 변환되며, 이 코드가 브라우저에서 실행되어 UI가 생성됩니다.

따라서, React 사용하여 생성된 페이지는 HTML 또는 XHTML 문서일 있지만, 직접적으로 React 코드가 XHTML 문서는 아닙니다.

 

 

3. 생명주기 함수 componentDidMount() 사용하기

 

App.js 를 수정하자.

import React from 'react';
import './App.css';
import R007_LifecycleEx from './R007_LifecycleEx';


function App() {
  return (
    <div>
      <h1>Start React 200!</h1>
      <p>CSS 적용하기</p>
      <R007_LifecycleEx
        prop_value = 'FromApp.js'
      />  
    </div>
  );
}

export default App;

이번에도 전과 마찬가지로 뒤에서 만들 파일을 미리 import 하고 시작하자.

 

 

src 폴더에 R007_LifecycleEx.js 파일을 생성하고 아래의 코드를 작성하자.

import React,{Component} from "react";

class R007_LifecycleEx extends Component {
    static getDerivedStateFromProps(props, state) {
        console.log('2. getDerivedStateFromProps Call :'+props.prop_value);
        return {tmp_state:props.prop_value};
    }

    constructor(props) {
        super(props);
        this.state = {};
        console.log('1. constructor Call');
    }

    componentDidMount() {
        console.log('4. componentDidMount Call');
        console.log('5. tmp_state : '+this.state.tmp_state);
    }
    render(){
        console.log('3. render Call');
        return (
            <h2>[THIS IS COMPONENTDIDMOUNT FUNCTION]</h2>
        )
    }
}
export default R007_LifecycleEx;
  • componentDidMount() 함수:
    • 작성한 함수들 중 가장 마지막으로 실행됨.
    • 위의 코드에서는 render() 함수가 return되는 html 형식의 코드를 화면에 그려준 후 실행됨.
    • 화면이 모두 그려진 후에 실행되어야 하는 이벤트 처리, 초기화 등에 가장 많이 활용되는 함수.
    • 생성 단계의 생명주기 함수 중 가장 마지막으로 실행됨

 

페이지를 실행하면

이렇게 뜨고 콘솔창은 다음과 같다.

componentDidMount 함수에서 정의해줬던 콘솔 명령문들이 이렇게 제일 마지막에 실행된 것을 볼 수 있다.

 

근데 저 tmp_state는 뭘까?

tmp_state와 관련된 코드에 대한 설명이 부족한 것 같아 찾아봤다.


코드에 대한 전체적인 설명은 다음과 같다.

 

이 컴포넌트는 React 생명주기 함수를 사용합니다. 각 생명주기 함수는 컴포넌트의 특정 시점에서 실행되며, 여기서는 다음과 같은 순서로 실행됩니다:

  1. constructor: 클래스 생성자 함수로, 컴포넌트가 생성될 실행됩니다. this.state 객체를 초기화하고, console.log 함수를 사용하여 생성자 함수가 호출되었음을 콘솔에 기록합니다.
  2. getDerivedStateFromProps: props와 state를 인자로 받아, props의 값이 state에 반영되기 전에 호출됩니다. console.log 함수를 사용하여 props.prop_value 값을 출력하고, 값을 tmp_state라는 새로운 상태 객체의 값으로 설정하여 반환합니다.
  3. render: 컴포넌트의 UI 렌더링하는 함수입니다. console.log 함수를 사용하여 함수가 호출되었음을 콘솔에 기록하고, <h2> 태그로 구성된 UI 반환합니다.
  4. componentDidMount: 컴포넌트가 처음으로 화면에 렌더링된 후에 실행됩니다. console.log 함수를 사용하여 함수가 호출되었음을 콘솔에 기록하고, this.state.tmp_state 값을 출력합니다.

Q. this.state.tmp_state 에 대해 더 자세히 설명해줘

A.

this.state.tmp_state는 R007_LifecycleEx 컴포넌트의 상태(state) 객체에서 tmp_state 속성을 참조하는 것입니다.

getDerivedStateFromProps 함수에서 props.prop_value 값을 tmp_state로 설정했기 때문에, componentDidMount 함수에서 this.state.tmp_state는 props.prop_value 값과 동일합니다.

this.state 객체는 컴포넌트의 상태를 저장하는 객체이며, 해당 상태가 변경될 때마다 React는 자동으로 컴포넌트를 다시 렌더링합니다. 따라서 getDerivedStateFromProps 함수에서 props.prop_value 값을 tmp_state로 설정하여 해당 값을 this.state.tmp_state에서 참조할 수 있게 되었습니다.

, this.state.tmp_state는 R007_LifecycleEx 컴포넌트의 현재 상태 나타내며, getDerivedStateFromProps 함수에서 초기화된 props.prop_value 값과 동일합니다. componentDidMount 함수에서 this.state.tmp_state 참조하여 해당 값을 출력할 있습니다.

 


Q. return {tmp_state:props.prop_value}; 이 코드에 대해 자세히 설명해줘

A.

getDerivedStateFromProps 함수에서 return {tmp_state:props.prop_value};는 컴포넌트의 상태를 변경하는 역할을 합니다.

React에서 컴포넌트는 상태(state) 객체와 속성(props) 객체를 가질 수 있습니다. 상태 객체는 컴포넌트 내부에서 변경할 수 있는 값이고, 속성 객체는 부모 컴포넌트로부터 전달받은 읽기 전용 값입니다.

getDerivedStateFromProps 함수는 props와 state를 인자로 받아서 호출되는 생명주기 함수입니다. 이 함수는 컴포넌트의 속성이 변경될 때마다 실행되며, props 값을 참조하여 state를 업데이트할 수 있습니다.

return {tmp_state:props.prop_value}; 구문은 tmp_state라는 이름으로 props.prop_value 값을 갖는 객체를 반환합니다. 이 객체를 반환하면 R007_LifecycleEx 컴포넌트의 상태 객체가 업데이트되어, this.state.tmp_state 값도 props.prop_value 값으로 변경됩니다.

따라서 getDerivedStateFromProps 함수에서 return {tmp_state:props.prop_value}; 구문은 props.prop_value 값을 R007_LifecycleEx 컴포넌트의 상태 객체에 업데이트하는 역할 합니다. 이후 componentDidMount 함수에서 this.state.tmp_state 값을 출력하면, 해당 값이 props.prop_value 값과 동일하게 출력됩니다.

 


Q. getDerivedStateFromProps 함수에서 tmp_state를 return 했는데 그게 어떻게 this.state.tmp_state가 되는거야?

A.

getDerivedStateFromProps 함수에서 return {tmp_state:props.prop_value}; 구문은 R007_LifecycleEx 컴포넌트의 상태(state) 객체를 업데이트합니다. tmp_state라는 이름으로 props.prop_value 값을 갖는 객체를 반환하기 때문에, 이 객체가 R007_LifecycleEx 컴포넌트의 새로운 상태가 됩니다.

React에서 상태(state)는 컴포넌트가 가지고 있는 내부 값이며, this.state로 참조할 수 있습니다. this.state.tmp_state는 R007_LifecycleEx 컴포넌트의 상태 객체에서 tmp_state 속성을 참조하는 것이기 때문에, getDerivedStateFromProps 함수에서 반환된 tmp_state 값과 동일합니다.

따라서 getDerivedStateFromProps 함수에서 return {tmp_state:props.prop_value}; 구문은 R007_LifecycleEx 컴포넌트의 상태 객체를 업데이트하고, this.state.tmp_state 값도 동일하게 변경됩니다. 이후 componentDidMount 함수에서 this.state.tmp_state 값을 출력하면, 해당 값이 props.prop_value 값과 동일하게 출력됩니다.

 


Q. tmp_state라는 변수는 뭘 의미하는걸까?

A. 

tmp_state는 getDerivedStateFromProps 함수에서 사용되는 임시 상태(state) 변수의 이름입니다.

getDerivedStateFromProps 함수는 컴포넌트의 속성(props)이 변경될 때마다 호출되며, props 값을 참조하여 상태를 업데이트할 수 있습니다. 이때 tmp_state 변수는 props.prop_value 값을 저장하는 임시 상태 변수로 사용됩니다.

tmp_state 변수의 역할은 단순히 props.prop_value 값을 다른 이름으로 저장하는 것뿐만 아니라, getDerivedStateFromProps 함수에서 반환된 객체에 tmp_state라는 이름으로 추가되어 컴포넌트의 상태 객체를 업데이트하는 역할도 합니다.

따라서 tmp_state 변수는 getDerivedStateFromProps 함수에서 사용되는 임시 상태 변수로, 컴포넌트의 속성(props) 값과 컴포넌트의 상태(state) 값을 연결하는 역할 합니다.


Q. getDerivedStateFromProps에서 반환하는 값은 무조건 this.state의 prop이 되는거야?

A.

getDerivedStateFromProps 함수에서 반환하는 값이 항상 this.state의 속성(prop)이 되는 것은 아닙니다.

getDerivedStateFromProps 함수는 컴포넌트의 속성(props)이 변경될 때마다 호출되며, props 값을 참조하여 상태를 업데이트할 수 있습니다. 이때 getDerivedStateFromProps 함수에서 반환하는 객체의 속성(prop)은 컴포넌트의 상태 객체(state)에 추가됩니다.

따라서 getDerivedStateFromProps 함수에서 반환하는 값은 this.state의 속성(prop)이 되는 것이 아니라, 컴포넌트의 상태 객체(state)의 속성(prop)이 됩니다. getDerivedStateFromProps 함수에서 반환하는 객체는 this.state에 직접 할당되는 것이 아니라, 상태 객체(state)의 속성(prop)으로 추가되기 때문입니다.

getDerivedStateFromProps 함수에서 반환하는 객체의 속성(prop)은 this.state에 직접 할당될 수도 있지만, this.state의 속성(prop)이 아닌 다른 객체에 할당되거나, 함수 내부에서만 사용되는 경우 있습니다. getDerivedStateFromProps 함수에서 반환하는 객체의 속성(prop) 개발자가 직접 정의하며, 컴포넌트의 상태 객체(state) 어떻게 추가할지에 따라 달라질 있습니다.


Q. 근데 왜 여기서는 this.state에 할당된거야?

A. 

getDerivedStateFromProps 함수에서 반환된 값이 this.state에 할당되는 이유는, 해당 컴포넌트에서 getDerivedStateFromProps 함수에서 반환한 값을 컴포넌트의 상태(state)에 추가하기 위해서 입니다.

컴포넌트의 상태(state)는 this.state 객체에 저장되며, 이 객체를 업데이트하기 위해서는 setState 함수를 호출해야 합니다. 그러나 getDerivedStateFromProps 함수에서는 setState 함수를 직접 호출할 수 없기 때문에, 함수의 반환값을 이용하여 상태(state)를 업데이트합니다.

따라서 getDerivedStateFromProps 함수에서 반환된 값은 컴포넌트의 상태(state)에 추가하기 위해서 this.state 객체에 할당되는 입니다. 이렇게 함으로써 getDerivedStateFromProps 함수에서 반환한 값은 this.state 객체의 속성(prop)으로 저장되어, 컴포넌트 내에서 this.state 객체의 속성(prop)처럼 사용할 있게 됩니다.

 

 

4. 생명주기 함수 shouldComponentUpdate() 사용하기

react에서 생명주기: component의 생성, 변경, 소멸

 

shouldComponentUpdate() 함수: component의 변경 과정에 속하는 함수

**여기서 변경이란 props나 state의 변경을 말함.

 

App.js를 수정하자.

import React from 'react';
import './App.css';
import R008_LifecycleEx from './R008_LifecycleEx';


function App() {
  return (
    <div>
      <h1>Start React 200!</h1>
      <p>CSS 적용하기</p>
      <R008_LifecycleEx
        prop_value = 'FromApp.js'
      />  
    </div>
  );
}

export default App;

 

R008_LifecycleEx.js 파일을 만들고 아래의 코드를 넣자.

import React,{Component} from "react";

class R008_LifecycleEx extends Component {
    constructor(props) {
        super(props);
        this.state = {};
        console.log('1. constructor Call');
    }

    static getDerivedStateFromProps(props, state) {
        console.log('2. getDerivedStateFromProps Call :'+props.prop_value);
        return {tmp_state:props.prop_value};
    }
    
    render() {
        console.log('3. render Call');
        return (
            <h2>[THIS IS shouldComponentUpdate FUNCTION]</h2>
        )
    }

    componentDidMount() {
        console.log('4. componentDidMount Call');
        console.log('5. tmp_state: '+this.state.tmp_state);
        this.setState({tmp_state2:true});
    }

    shouldComponentUpdate(props,state) {
        console.log('6. shouldComponentUpdate Call / tmp_state2= '+state.tmp_state2);
        return state.tmp_state2;
    }
}

export default R008_LifecycleEx;
  • componentDidMount() 함수: 생성단계의 생명주기 함수 중 가장 마지막으로 실행됨.
  • setState() 함수: 변수의 선언과 초기화를 동시에 선언
    • tmp_state라는 state변수에 true라는 boolean 데이터를 세팅함
  • componentDidMount 함수의
this.setState({tmp_state2:true});

코드에서 state의 변경이 발생했기 때문에 '변경' 단계의 생명주기함수 shouldComponentUpdate()가 실행됨.

  • shouldComponentUpdate()는 boolean 유형의 데이터를 반환함. 이때 return값이 true일 경우에 render() 함수를 한번 더 호출함.

▶ shouldComponentUpdate() 함수의 변환값에 따라 render() 함수를 재실행할 수 있다는 점을 이용하면, props나 state 변수가 변경될 때 화면을 다시 그리면서 제어할 수 있음.

 

콘솔에는 다음과 같이 출력된다.

왜 이렇게 되는지 하나하나 따져보자.

1. constructor Call : constructor(props)는 생명주기 함수 중 가장 먼저 실행됨.

 

2. getDerivedStateFromProps Call :FromApp.js :

App.js에서 import한 R008_Lifecycle 컴포넌트로 prop_value라는 변수를 전달해주며

컴포넌트가 새로운 props를 받게 되었기 때문에

<R008_LifecycleEx
        prop_value = 'FromApp.js'
      />

getDerivedStateFromProps(props, state)함수가 실행되었다.

근데 getDerivedStateFromProps(props, state)함수는 무조건 constructor(props) 함수 다음으로 실행되기 때문에  두번째로 실행된 것이다.

 

3. render Call : 화면이 변경되어야 할 시점에 자동으로 호출되어 return되는 html 형식의 코드를 화면에 그려주었다.

 

4. componentDidMount Call :

생성 단계의 constructor(), getDerivedStateFromProps(), render(), componentDidMount() 함수들 중 가장 마지막으로 실행된다.

componentDidMount 함수는 render 함수 다음에 실행된다.

 

5. tmp_state: FromApp.js:

componentDidMount() 함수가 실행되며 출력된다.

두번째로 실행되었던 getDerivedStateFromProps() 함수에서 tmp_state가 'FromApp.js'가 되었다는 것을 보여준다.

 

2. getDerivedStateFromProps Call :FromApp.js :

네번째로 실행되었던 componentDidMount() 함수에서

this.setState({tmp_state2:true});

코드를 통해 

컴포넌트가 tmp_state2라는 새로운 props를 받게 되었기 때문에

getDerivedStateFromProps() 함수가 실행되었다.

 

6. shouldComponentUpdate Call / tmp_state2= true:

바로 위의 단계에서 getDerivedStateFromProps() 함수가 실행되어

새로운 props를 받으며 state를 변경해주었기 때문에

state의 변경이 발생했고

shouldComponentUpdate() 함수가 실행되었다.

이때, 네번째로 실행되었던 componentDidMount() 함수의

this.setState({tmp_state2:true});

코드로 

tmp_state2의 값이 true로 초기화되었다.

 

3. render Call :

shouldComponentUpdate() 함수의 반환값이 state.tmp_state2의 초깃값 true이므로 render() 함수가 한 번 더 호출되었다.

'Front-End > React' 카테고리의 다른 글

[React] useMemo  (0) 2023.12.27
[React] Describing the UI  (0) 2023.06.05
[React] 230501 학습일기  (0) 2023.05.01
[React] 220416 학습일기  (1) 2023.04.17
[ReactJS] 코드 모음  (0) 2023.04.03