본문 바로가기

Front-End

[React] 230417 학습일기

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

 

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

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

www.yes24.com

 


1.

src 폴더의 index.js에서

<React.StrictMode>
</React.StrictMode>

태그를 삭제했다.

 

Strict모드: - 어플리케이션 내의 잠재적 문제를 알아내기 위한 도구.

- 생명 주기 함수를 여러번 실행하는 원인

 

책에서는

import * as serviceworker from './serviceworker';

.
.
.
serviceWorker.unregister();

썼는데

 

내 index.js에는

import reportWebVitals from './reportWebVitals';
.
.
.
reportWebVitals();

로 되어있어서

 

챗gpt에 물어보았다.

 

둘은 서로 다른 함수이기 때문에 책과 같이 맞춰주는 게 좋을 것 같다.

배포용은 뒤에서 따로 설명한다고 했기 때문에 개발하는 동안은 serviceWorker.unregister()을 써주도록 하려고 했는데???

 

안 써줘도 될 것 같다.

 

 

 

 

그래서 최종결론은

src 폴더 안의 index.js는 다음과 같다.

이건 책에서 하라는 방식

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';

ReactDOM.render(
  <App/>,
  document.getElementById('root')
)

이거는 react를 설치하며 프로그램에서 제공하는 방식

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
    <App />
);

 

그래서 또 물어봤다.

둘 중 뭘 더 추천하냐고.


두 코드 모두 React 애플리케이션을 렌더링하는 데 사용할 수 있습니다. 그러나 ReactDOM.createRoot() 메서드를 사용하는 것이 더 최신 방법입니다. React v17 이상에서는 ReactDOM.render() 대신에 ReactDOM.createRoot() 메서드를 사용하여 루트 렌더러를 만드는 것이 권장됩니다.

createRoot() 메서드는 초기 렌더링 이후에도 업데이트가 가능한 Concurrent 모드를 지원합니다. 이 방법을 사용하면 React의 성능과 유연성을 더욱 향상시킬 수 있습니다. 또한, createRoot() 메서드를 사용하면 Suspense 기능을 사용하여 데이터를 미리 가져와 렌더링할 수 있습니다.

따라서, React v17 이상을 사용한다면, ReactDOM.createRoot() 메서드를 사용하는 것이 권장되는 방법입니다.


프로그램에서 제안하는 createRoot()를 사용한 방식을 사용해야겠다.

 

2.

React 프로젝트

react 프로젝트에서는 react 경로에서

npm install

 

명령어를 실행.

 

같은 경로에서 

npm start

명령어로 서버를 구동한다.

 

react, node 프로젝트

react, node 프로젝트에서는 react와 node 경로에서 각각

npm install

명령어를 실행한 후,

yarn dev

명령어로 react, node 서버를 동시에 구동한다.

 

react, node  폴더 경로에는 package.json 파일이 있음.

여기에 프로젝트에서 사용하는 npm 패키지 리스트가 작성되어 있음.

npm install

혹은

yarn install

을 실행하면

package.json 파일에 있는 패키지 리스트가 설치됨.

 

 

package.json 파일을 찾아보려 했으나.. 컴퓨터에 node 폴더가 너무 많은 관계로 패스.

 

 

 

3.

생명주기: 컴포넌트의 생성부터 소멸까지의 과정

 

 

4.

홈 화면: 

http://localhost:3000/

또는

127.0.0.1:3000

과 같이 상세 url이 붙지 않는 웹사이트의 대표 페이지

 

 

5. .jsx에 html 적용하기

App.js를 이렇게 수정해보았다.

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

function App() {
  return (
    <div>
      <h1>Start React 200!</h1>
      <p>HTML 적용하기</p>
    </div>
  );
}

export default App;

스타일이 적용되지 않은 기본 HTML 코드만 삽입된 상태다.

페이지를 열면 이렇게 된다,

 

 

6.

근데 jsx가 뭘까

위의 예제는 jsx에 html을 적용하는 거였다.

 

https://goddaehee.tistory.com/296

 

[React] 2. JSX란? (정의, 장점, 문법)

2. JSX란? (정의, 장점, 문법) 안녕하세요. 갓대희 입니다. 이번 포스팅은 [ [React 에서 사용하는 JSX ] 입니다. : ) 이번엔 React에서 자주 사용하게될 JSX에 대해 알아보도록 하자. 1. JSX란? - JSX(JavaScript X

goddaehee.tistory.com

정리하자면

JSX(JavaScript XML):

  • Javascript에 XML을 추가한 확장한 문법
  • 리액트로 프로젝트를 개발할 때 사용됨.
  • 공식적인 자바스크립트 문법은 아님.
  • 브라우저를 실행하기 전에 바벨을 사용하여 일반 자바스크립트 형태의 코드로 변환됨.
  • JSX는 하나의 파일에 자바스크립트와 HTML을 동시에 작성함 => 편리
  • 자바스크립트에서 html 작성하듯이 하기 때문에 가독성이 높고 작성하기 쉬운

 

음 좋은 거구나. 알겠다.

 

근데 여기서 또 xml이 뭔지 궁금해진다.

그래서 찾아봤다.

 

https://aws.amazon.com/ko/what-is/xml/

 

XML이란 무엇인가요? - Extensible Markup Language(XML) 설명 - AWS

비즈니스 간 트랜잭션 지원 회사가 다른 회사에 상품이나 서비스를 판매하는 경우 두 기업은 비용, 사양 및 배송 일정과 같은 정보를 교환해야 합니다. XML(Extensible Markup Language)을 사용하면 필요

aws.amazon.com

 

뭔가 알 것 같으면서도 아직은 이해가 안되는 개념이다. 일단 넘어가자.

 

 

7. .jsx에 css 적용하기

 

css는 html 문서에 스타일을 적용할 때 사용하는 언어.

 

App.css 파일을 아래와 같이 수정했다.

div {
  background-color: rgb(162,127,243);
  color: rgb(255,255,255);
  padding: 40px;
  font-family: 고딕;
  text-align: center;
}

h1 {
  color: white;
  background-color: #2EFE2E;
  padding: 10px;
  font-family: 궁서;
}

 

App.js 파일도 수정해보자.

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

function App() {
  return (
    <div>
      <h1>Start React 200!</h1>
      <p>CSS 적용하기</p>
    </div>
  );
}

export default App;

코드를 살펴보면

App.js와 같은 폴더 경로에 위치한 App.css를 import한다.

 

만약 App.css가 App.js보다 한 단계 상위 폴더에 위치한다면 

import './../App.css';

와 같이 사용해 상위 경로에  접근해야 한다.

 

페이지를 열면 다음과 같다.

 

 

8. component 사용하기

component: 특정 코드 뭉치를 다른 부분에 이식하거나 재사용하기 위해 사용하는 코드 블록 단위

component를 파일 단위로 작성한 후 필요한 위치에서 임포트해 사용할 수 있음.

 

R003_ImportComponent.js를 새로 생성해서 다음과 같이 코드를 작성했다.

import React,{Component} from "react"; 

class R003_ImportComponent extends Component { //첫번째 줄에서 임포트한 component를 상속받아 R003_ImportComponent 클래스에서 사용함.
    render() {  //아래에서 return 된 html 코드를 render() 함수를 사용해 화면에 표시한다.
        return (
            <h2>[THIS IS IMPORTED COMPONENT]</h2>
        )
    }
}

export default R003_ImportComponent;

맨 아래 export default ~ 코드에 대해 알아보자.

 

 

역시 똑똑하다.


App.js 파일을 수정해보자.

 

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

function App() {
  return (
    <div>
      <h1>Start React 200!</h1>
      <p>CSS 적용하기</p>
      <R003_ImportComponent></R003_ImportComponent>
    </div>
  );
}

export default App;

App.js 와 같은 경로에 위치한 R003_ImportComponent.js 를 import하여 사용할 수 있게 했다.

R003_ImportComponent.js에서 작성한 R003_ImportComponent라는 component를 사용했다.

이때 render()함수에서 읽어들였던 

<h2>[THIS IS IMPORTED COMPONENT]</h2>

코드가 이식된다.

 

 

홈페이지에는 다음과 같이 실행된다.

 

 

9. 생명주기 함수 render() 사용하기

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

 

component의 생성 과정에 속하는 함수: render(), constructor(), getDerivedStateFormProps(), componentDidMount()

 


여기서 딴 이야기이지만

import React,{Component} from "react";

이런 import 문이 있을 때

아마도 react.js 라는 파일에서

React 라는 모듈 혹은 컴포넌트는 export default로 기본 내보내기 했고

Component라는 모듈 혹은 컴포넌트는 export 로 이름 지정하여 내보내기 를 한 것 같다.


R004_LifecycleEx.js라는 파일을 만들고 다음과 같이 코드를 쓰자.

import React,{Component} from "react";

class R004_LifecycleEx extends Component {
    render() {
        console.log('3. render Call');
        return (
            <h2>[THIS IS RENDER FUNCTION]</h2>
        )
    }
}

export default R004_LifecycleEx;

render():

- return되는 html 형식의 코드를 화면에 그려주는 함수. 

- 화면 내용이 변경되어야 할 시점에 자동으로 호출된다.

 

 

App.js도 다음과 같이 바꿔주자.

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


function App() {
  return (
    <div>
      <h1>Start React 200!</h1>
      <p>CSS 적용하기</p>
      <R004_LifecycleEx></R004_LifecycleEx>
    </div>
  );
}

export default App;

- App.js 와 같은 경로에 위치한 R004_LifecycleEx.js 파일을 import해 사용할 수 있도록 했다.

- 아래의 코드를 통해 R004_LifecycleEx.js에 있는 R004_LifecycleEx라는 컴포넌트를 이식한다.

<R004_LifecycleEx></R004_LifecycleEx>

 

웹페이지는 다음과 같이 실행된다.

 

콘솔에서 render함수에서 출력된 로그를 볼 수 있다.

 

10. 생명주기함수 constructor(props) 사용하기

src 폴더에 R005_LifecycleEx.js 파일을 생성한 뒤 아래의 코드를 입력했다.

import React, {Component} from "react";

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

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

export default R005_LifecycleEx;

- constructor(props) 함수는 생명주기 함수 중 가장 먼저 실행된다. 그리고 처음 한 번만 호출된다.

  • component 내부에서 사용되는 변수(state)를 선언하고 부모 객체에서 전달받는 변수를 초기화할 때 사용한다.
  • super() 함수는 가장 위에 호출해야 함.

근데 이렇게만은 이해가 안 돼서 또 챗 선생님께 여쭤봤다.

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

이 부분을 중점적으로 물어봤다.

 


이 코드는 리액트 컴포넌트의 constructor 함수를 정의하는 부분입니다. constructor 함수는 클래스를 정의할 때 항상 호출되며, 컴포넌트의 초기 설정을 담당합니다.

여기서는 super(props)를 호출하여 부모 클래스인 Component의 constructor를 먼저 실행하고, 그 다음에 this.state를 빈 객체로 초기화합니다.

또한, console.log('1. constructor Call') 코드를 추가하여 컴포넌트가 생성될 때 "1. constructor Call" 이라는 메시지가 콘솔에 출력되도록 하였습니다.

코드를 통해, 컴포넌트의 초기 state 값 설정하고, 이를 constructor 함수에서 처리할 있음을 있습니다.

 


Q. class 정의할 때 constructor 함수를 안 써줘도 클래스 정의할 때 항상 호출돼?

A.

네, 클래스를 정의할 때 항상 constructor 함수는 호출됩니다.

만약 클래스에서 constructor 함수를 정의하지 않으면, 자동으로 빈 constructor 함수가 생성됩니다. 따라서, 클래스를 정의할 때 constructor 함수를 작성하지 않아도 됩니다.

하지만, 만약 constructor 함수에서 초기 state 값을 설정하거나, 함수에서 사용할 변수를 초기화하는 등의 작업을 수행해야 한다면, constructor 함수를 작성해야 합니다. 이렇게 constructor 함수를 사용하면 클래스가 생성될 초기화 작업 수행할 있습니다.


Q. constructor 함수의 역할은 뭐야?

A.

constructor 함수는 자바스크립트 클래스의 생성자 함수입니다.

리액트에서 컴포넌트를 정의할 때 constructor 함수컴포넌트가 생성될 때 초기화 작업을 수행하는 역할을 합니다. 이 함수에서는 컴포넌트의 초기 state 값을 설정하거나, 함수에서 사용할 변수를 초기화하는 등의 작업을 수행할 수 있습니다.

또한, constructor 함수는 부모 클래스의 생성자 함수를 호출하기 위해 super(props)를 호출하는 역할도 합니다. 이를 통해 부모 클래스에서 정의된 속성과 메서드를 자식 클래스에서 사용할 수 있습니다.

따라서, constructor 함수는 컴포넌트의 초기화 작업을 수행하고, 부모 클래스의 생성자 함수를 호출하여 자식 클래스에서 상속받은 속성과 메서드를 사용할 있게 해주는 역할을 합니다.

 


Q. 

import React, {Component} from "react";

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

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

export default R005_LifecycleEx;

여기에서 super 함수가 하는 역할이 뭐야?

A.

super(props) 함수는 부모 클래스인 Component의 constructor 함수를 호출하는 역할을 합니다.

React 컴포넌트는 Component 클래스를 상속받아서 만들어지기 때문에, constructor 함수에서 super(props) 함수를 호출해야 합니다. 이를 호출하지 않으면, 컴포넌트에서 this 키워드를 사용할 수 없게 됩니다. super 함수를 호출하면, Component 클래스가 가지고 있는 메서드와 속성을 자식 클래스에서 사용할 수 있게 됩니다.

또한, constructor 함수에서 props 전달하여 부모 클래스에서 상속받은 속성을 사용할 수 있게 됩니다. 이렇게 부모 클래스의 constructor 함수를 호출하고, props 전달하는 것은 리액트 컴포넌트에서 초기 설정을 수행하는 중요한 역할을 합니다.

 


Q. 여기서 constructor 함수를 정의 안 해주면 부모인 Component 클래스의 메서드와 속성을 못 쓰는거야?

A.

아니요, constructor 함수를 정의하지 않아도 부모 클래스인 Component의 메서드와 속성을 사용할 수 있습니다.

constructor 함수가 명시적으로 정의되어 있지 않으면, 자동으로 빈 constructor 함수가 생성됩니다. 이 경우, 자식 클래스에서는 부모 클래스의 constructor 함수가 자동으로 호출됩니다.

따라서, constructor 함수를 정의하지 않아도 부모 클래스의 메서드와 속성을 사용할 수 있습니다. 하지만, 만약에 자식 클래스에서 constructor 함수를 정의하고, 부모 클래스의 constructor 함수를 호출하지 않는다면, 부모 클래스의 메서드와 속성을 사용할 수 없게 됩니다. 이때는, super(props) 함수를 호출하여 부모 클래스의 constructor 함수를 명시적으로 호출해야 합니다.

 


위의 코드에서 super(props)의 의의는 this라는 키워드를 사용할 수 있게 한 데에 있다.

this.state 를 빈 객체로 초기화한다.

 

근데 여기서 또 의문이 생긴다.

왜 this.state를 빈 객체로 초기화하는가?

 


Q. this.state는 왜 빈 객체로 초기화하는거야?

A.

React 컴포넌트에서 state는 컴포넌트의 상태를 나타내는 객체입니다. 이 state 객체는 컴포넌트가 생성될 때 초기화되고, 컴포넌트가 업데이트될 때마다 변경됩니다.

constructor 함수에서 this.state를 빈 객체로 초기화하는 이유는, 컴포넌트가 생성될 때 초기 상태를 설정하기 위해서입니다. 빈 객체로 초기화하면, 컴포넌트가 생성될 때 state 값이 없는 상태로 초기화되고, 나중에 setState() 함수를 호출하여 값을 변경할 수 있습니다.

예를 들어, 다음과 같이 초기 state 값을 설정해줄 있습니다.

constructor(props) {
  super(props);
  this.state = {
    count: 0
  };
}

경우, count라는 이름의 속성을 가지는 객체를 초기 state로 설정하고 있습니다. 만약 초기 값이 없다면, 객체로 초기화해도 상관없습니다. 초기 state를 빈 객체로 설정하면, setState() 함수를 호출하여 값을 변경할 때 state 객체가 항상 존재하므로 에러를 방지 있습니다.

 


이제 App.js 를 수정해보자.

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


function App() {
  return (
    <div>
      <h1>Start React 200!</h1>
      <p>CSS 적용하기</p>
      <R005_LifecycleEx></R005_LifecycleEx>
    </div>
  );
}

export default App;

 

홈페이지에서는 다음과 같이 실행된다.

 

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

잘 된다. 굿