Component, Props

zzwwoonn·2021년 10월 30일
0

React

목록 보기
2/23

React 란 무엇인지, 정의와 특징에 대해 간단히 정리했고 초기 셋팅 후 실행까지 해보았습니다. 다음으로 리액트의 기본적인 내용들 !! 배포하는 법부터 리액트의 핵심!! ComponentPropsState에 대해서 자세하게 알아봅시다 🔥

배포하는 법 (deploy)

제일 처음 예제로 만들었던 Hello, React !! 라는 h1 태그 하나만 들어있는 간단한 리액트 앱이 있습니다. npm start로 앱을 실행시켰을 때, 앱의 전체 용량이 1.7MB 라고 나옵니다. 기능이 하나도 없는데, 이런 용량이 나오는 것은 도저히 이해가 안됩니다.

이는 바로 리액트가 개발의 편의성을 위해서 여러가지 기능을 추가해놓은 상태이기 때문입니다. create react app 의 개발 환경은 파일의 무게가 상당히 나무겁습니다. 하지만 개발자만 사용하고 로컬에서만 사용하기 때문에 괜찮습니다. 근데 사람들이 쓸 때는 1.7MB를 쓰게하면 절대 안되겠죠!? (보안의 문제도 있을 수 있고.. 이러쿵 저러쿵...)

create react app 에서의 개발 환경을 실행시킬 때는 npm run start(npm srart)를 쎴는데, production mode 의 app 을 만들 때(빌드할 때)는 npm run build를 이용합니다. 그러면 디렉토리에 이전에는 없었던 build 라는 내부(하부) 디렉토리가 새로 생깁니다. 그 안에 보면 index.html 이 있습니다. 한번 까봅시다 ✌️

😱 공백이 하나도 없고, 아예 읽을수가 없습니다... 간혹 알아볼 수 있는 단어가 조금 보이기도...? 이는 create react app 이 실제 production 환경에서 사용되는 app을 만들기 위해서, 이미 가지고 있는 index.html 에서 불필요한 정보를 다 걸러낸 결과물이기 때문입니다. (=> 용량이 매우 작다!!!)
src 에서 작업했던 소스코드들도 전부 마찬가지 입니다.

실제로 서비스할 때는 build 안에 있는 파일들을 쓰면 됩니다. (이것들이 바로 공정 과정을 거친 알짜배기들? 이라고 이해하면 좀 쉬울까요??) 웹 서버에 도큐먼트 루트(문서를 찾는 최상위 디렉토리)에다가 build 안의 파일들을 위치시키면 됩니다!

컴포넌트(Component)

왼쪽의 html 코드가 있습니다. 이를 Js-리액트로 다시 작성해보았습니다.
만약 왼쪽의 header, nav, article (이들을 시멘틱 코드라고 합니다.) 의 길이가
천만 라인, 1억 라인 등으로 엄청나게 길어진다면 어떻게 될까요?

이 코드들을 유지보수하고 수정하는데에 엄청난 시간을 쓰게 될 것입니다.
그렇다면 개발자는 이러한 생각을 하게 될 것입니다.
"header 라는 이름으로 가져다 쓰기만 하고 안에 내용들은 다른 데다가 정의 해두면 안될까?" 다음과 같은 생각을 구현하게 해주는 것이리액트이고,
바로 리액트의 컴포넌트 개념이라고 할 수 있습니다. 컴포넌트를 정의하는 가장 간단한 방법은 JavaScript 함수를 작성하는 것입니다. 위의 그림에서 오른쪽 !!

이렇게 리팩토링을 해줘도, 하나의 파일에 수천개의 컴포넌트가 있다면 그것 또한 보기가 혼란스럽습니다. 그래서 보통의 경우에 컴포넌트를 파일로 분리해서 주로 사용합니다⭐️

여기서 잠깐 !! React Component 선언하는 방식에는 두 가지가 있습니다. 클래스형 컴포넌트함수형 컴포넌트. 현재 공부하고 있는 생활코딩에서는 클래스형 컴포넌트로 설명을 해줍니다.(아무래도 옛날 강의라서,,ㅠ)
React의 최신 문법에 따르면 함수형 컴포넌트를 사용하고 권장합니다.
그럼에도 불구하고? 클래스형 컴포넌트를 사용하는 기업들이 간혹 있습니다..!
이 둘의 차이점에 대해서 한번 알아보고 프롭스(Props)로 넘어가겠습니다 ✌️

함수령 컴포넌트와 클래스형 컴포넌트

선언 방식

< 함수형 컴포넌트 >

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

function App() {
  const name = 'react';
  return <div className = "react">{name}</div>
}

export default App;

< 클래스형 컴포넌트 >

import React, {Component} from 'react';

class App extends Component {
  render() {
    const name = 'react';
    return <div className="react">{name}</div>
  }
}

export default App;

함수형과는 다른 클래스 컴포넌트의 핵심은 크게 3가지입니다.

  • class 키워드가 필요하다.
  • render() 메소드가 반드시 있어야한다.
  • Component로 상속을 받아야 한다.

일반적인 차이점으로

클래스형에서는 state, lifeCycle 관련 기능을 사용할 수 있다는 점, 메모리 자원을 함수형 컴포넌트보다 조금 더 사용한다는 점, 임의 메서드를 정의할 수 있다는 점 등이 있습니다.

함수형은 state, lifeCycle 관련 기능사용 불가능하고(Hook을 통해 해결) 메모리 자원을 함수형 컴포넌트보다 덜 사용한다, 컴포넌트 선언이 편하다. 라는 점들이 있습니다.

StateProps의 사용에서도 큰 차이점이 있습니다. 이는 State와 Props를 공부하면서 같이 살펴보도록 하겠습니다!

프롭스(Props)

프롭스(props) 는 컴포넌트(Component)에서 사용 할 데이터 중 변동되지 않는 데이터를 다룰 때 사용됩니다. 또한 부모(parent) 컴포넌트에서 자식(child) 컴포넌트로 데이터를 전할 때, props 가 사용됩니다.

예를 들어, Content 라는 컴포넌트를 2개 만들었는데 이게 계속 같은 역할만 수행합니다. naver a태그를 이용하여 h1태그를 만든다고 가정하면 개발자는 이런 고민을 할 수 있습니다.

"동작은 똑같은데 그 안에 내용만 조금씩, 내가 원하는거로 바꿔줄 수는 없나?
전달해준 인자를 적용해줄 수는 없나?"

여기서 나온 개념이 바로 props 입니다!

클래스형으로 예제를 만들어보면 다음과 같습니다.

< 선언 방식 >

클래스 컴포넌트의 props

class MyComponent extends Component {
  render() {
    const {dept, id, name} = this.props;
    return{
      <div>
        안녕하세요! 저는 {dept}, {id}, {name} 입니다.
      </div>
    };
  }
}

함수형 컴포넌트의 props

function MyComponent = ({dept, id, name}) => {
  return (
    <div>
    안녕하세요! 저는 {dept}, {id}, {name} 입니다.
    </div>
  )
}

< 이벤트 핸들링 >

클래스형 컴포넌트

함수 선언시 에로우 화살로 바로 선언 가능합니다. 요소에서 적용하기 위해서는 this를 붙여야합니다.

함수형 컴포넌트에서 이벤트 핸들링

const 키워드 + 함수 형태로 선언 해야합니다. 요소에서 적용하기 위해서는 this가 필요없습니다.

[그림 출처] - sdc337dc.log, < 함수형과 클래스형의 차이 >

스테이트(State)

컴포넌트에서 유동적인 데이터를 다룰 때, 스테이트(State)를 사용합니다.
Props가 읽기 전용이라면 State는 컴포넌트 내부에서 바꿀 수 있는, 바뀔 수 있는 값 !!

프롭스는 사용자가 컴포넌트를 사용하는 입장에서 중요한 것이고, 스테이트는 프롭스의 값에 따라 내부 구현에 필요한 데이터라고 구분해서 이해 가능합니다!

사용자는 태그의 속성에 해당하는 프롭스를 통해 컴포넌트를 조작합니다. 사용자는 컴포넌트 내부에서 사용되는 동작, 구현 방식에 대해서는 아무것도 모릅니다. 이게 바로 스테이트 입니다.

리액트와 같은 시스템은 컴포넌트를 만들고 외부에서의 프롭스, 그리고 실제로 내부에서의 스테이트가 철저히 구분되어 있습니다. 사용하는 쪽과 구현하는 쪽이 철저히 구분되어 있는 것입니다.

클래스형으로 예제를 만들어보면 다음과 같습니다.

선언 방식

클래스 형 컴포넌트

constructor 안에서 this.state 초기 값 설정 가능하고 state는 객체 형식입니다. 컴포넌트가 실행될 때 render 메소드보다 먼저 실행이 되면서 그 컴포넌트를 초기화 시켜주고 싶은 내용들은 constructor 안에다가 작성해줍니다.

constructor(props) {
  super(props);
  this.state = {
  	monsters : [],
    userInput: "",
  };
}

this.setState 함수로 state의 값을 변경할 수 있습니다.

onClick={() => {
this.setState({number:number+1});
}}

함수형 컴포넌트

함수형 컴포넌트에서는 useState 함수로 state를 사용합니다. useState 함수를 호출하면 배열이 반환되는데 첫 번째 원소는 현재 상태, 두 번째 원소는 상태를 바꾸어 주는 함수입니다.

const [message, setMessage] = useState("");

상태를 바꿔주는 함수는 보통 set + 원소 이름(첫문자는 대문자)로 사용합니다.

가장 많이 쓰이는 개념은 상위 컴포넌트의 상태를 하위 컴포넌트로 전달하고 싶을 때 상위 컴포넌트의 스테이트 값을 하위 컴포넌트의 프롭스 값으로 전달하기! 입니다.

데이터가 바뀌어도 하위 컴포넌트에 직접 접근해서 코드를 수정하지 않아도 되게 되는 것입니다! (말이 좀 이상한가요ㅠ) 이해가 되셨으면 좋겠습니다 !!

0개의 댓글