React - Component와 props

Noma·2021년 4월 9일
0

1. React Component

컴포넌트를 통해 UI를 재사용 가능한 개별적인 여러 조각으로 나눌 수 있고, 개념적으로 JavaScript 함수와 유사하다.

props라고 하는 임의의 입력을 받은 후, 화면에 어떻게 표시되는지를 기술하는 React Element를 반환한다. 이는 함수 컴포넌트와 클래스 컴포넌트로 나뉜다.

1.1 클래스 컴포넌트

리액트에서 제공하는 React.Component 클래스를 상속해서 만들 수 있다.

class Welcome extends React.Component{
	render(){
    	return <h1>hello, {this.props.name}</h1>;
    }
}
  • UI가 어떻게 표기될 것인지를 정의하는 render() 함수를 구현해야 한다.(필수)

  • state(상태)가 있고 그 상태에 따라서 컴포넌트가 주기적으로 업데이트되어야 할 때 사용한다.

  • state(상태)란?
    - UI를 표기하기 위한 데이터를 담을 수 있는 오브젝트를 말함
    - state가 변경되면 리액트가 알아서 render함수를 호출해 업데이트 된 내용을 사용자에게 보여준다.

  • lifecycle methods가 있다.

  • 생성 단축키: rcc

state 및 lifecycle methods는 다른 포스팅에서 자세히 다룬다.

1.2 함수 컴포넌트

컴포넌트를 정의하는 가장 간단한 방법으로 아래와 같이 JSX를 반환하는 함수를 정의하면 된다.

function Welcome(props){
	return <h1>Hello, {props.name}</h1>;
}

<리액트 16.8버전 이전>

  • 컴포넌트 자체 데이터(state)가 없이 props만 보여주면 되거나, 둘다 없는 정적인 컴포넌트를 표기할 때 사용한다.
  • 함수의 특성상 호출될 때마다 코드 블럭이 전부 다시 실행되므로, 그 안에 선언된 지역 변수들은 재정의/재할당 되어진다.
  • lifecycle methods가 없다.
  • 생성 단축키 : rsi

<React Hook 도입 이후>

  • useState, useEffect.. 등을 통해 class component의 state와 lifecycle methods와 같은 기능 구현이 가능해졌다.

자세한 건 다른 포스팅에서 다룬다.

2. Component Rendering

React Element는 사용자 정의 컴포넌트로 나타낼 수 있다.

<Welcome name="Sara" onClick={handleClick}/>;

2.1 props

props는 컴포넌트 밖에서 주어지는 데이터(객체)로, React가 사용자 정의 컴포넌트(여기선 <Welcome/>)를 발견하면 해당 컴포넌트에 단일 객체로 전달하는 것을 말한다.

  • 위의 예시처럼 부모 컴포넌트에서 Welcome 컴포넌트를 사용하면 name, onClick에 해당하는 것들이 props 오브젝트로 묶여서 Welcome 컴포넌트로 전달된다. 그러면 Welcome 안에서 this.props.name, this.props.onClick으로 각각 전달된 'Sara'와 this.handleClick함수를 접근해 사용할 수 있게 된다.

  • props는 읽기 전용 으로 컴포넌트의 자체 props를 수정해서는 안된다. 반드시 순수 함수처럼 동작해야 한다.

🔍순수함수란?
아래와 같이 입력값을 변경하지 않고 항상 동일한 입력값에 대해 동일한 결과를 반환하는 함수를 말함

function sum(a,b){
	return a+b;
}

2.2 실행 과정

function Welcome(props){
	return <h1>Hello, {props.name}</h1>;
}
const element =<Welcome name="Sara" />;
ReactDOM.render(
	element,
  	document.getElementById('root')
);
  1. <Welcome name="Sara" />엘리먼트로 ReactDOM.render()를 호출
  2. React는 {name:'Sara'}를 props로 하여 Welcome 컴포넌트를 호출
  3. Welcome 컴포넌트는 <h1>Hello, Sara</h1>를 반환
  4. ReactDOM은 <h1>Hello, Sara</h1>와 일치하도록 DOM을 효율적으로 업데이트

❗ 주의: 컴포넌트 이름은 항상 "대문자"로 시작
React는 소문자로 시작하는 컴포넌트를 DOM 태그로 처리한다.
e.g. <div/> → HTML div 태그, <Welcome /> → 컴포넌트

3. Component 합성

컴포넌트는 자신의 출력에 다른 컴포넌트를 참조할 수 있다.

e.g. Welcome을 여러 번 렌더링하는 App 컴포넌트
(일반적으로 새 React 앱은 최상위에 단일 App 컴포넌트를 가지고 있음)

function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}

function App() {
  return (
    <div>
      <Welcome name="Sara" />
      <Welcome name="Cahal" />
      <Welcome name="Edite" />
    </div>
  );
}

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

4. Component 추출

컴포넌트를 여러 개의 작은 컴포넌트로 나누는 것을 말한다.

function Comment(props) {
  return (
    <div className="Comment">
      <div className="UserInfo">
        <img className="Avatar"
          src={props.author.avatarUrl}
          alt={props.author.name}
        />
        <div className="UserInfo-name">
          {props.author.name}
        </div>
      </div>
      <div className="Comment-text">
        {props.text}
      </div>
      <div className="Comment-date">
        {formatDate(props.date)}
      </div>
    </div>
  );
}

이 컴포넌트는 author, text, date을 props로 받은 후 웹 사이트의 코멘트를 나타낸다. 여기서 Avater를 추출해 보자.

function Avatar(props) {
  return (
    <img className="Avatar"
      src={props.user.avatarUrl}
      alt={props.user.name}
    />
  );
}

Avatar는 자신이 Comment내에서 렌더링 된다는 것을 알 필요가 없다. 따라서 props의 이름을 author에서 더욱 일반화된 user로 변경하자.

❗ props의 이름은 사용될 context가 아닌 "컴포넌트 자체의 관점" 에서 짓는 것을 권장한다.

function Comment(props) {
  return (
    <div className="Comment">
      <div className="UserInfo">
        <Avatar user={props.author} />
        <div className="UserInfo-name">
          {props.author.name}
        </div>
      </div>
      <div className="Comment-text">
        {props.text}
      </div>
      <div className="Comment-date">
        {formatDate(props.date)}
      </div>
    </div>
  );
}

이러한 방법으로 컴포넌트들을 추출해내면 상위 컴포넌트가 보다 단순해 질수 있다.

function Comment(props) {
  return (
    <div className="Comment">
      <UserInfo user={props.author} />
      <div className="Comment-text">
        {props.text}
      </div>
      <div className="Comment-date">
        {formatDate(props.date)}
      </div>
    </div>
  );
}

이렇듯 재사용 가능한 컴포넌트들을 만들어 놓으면 더 큰 앱에서 작업할 때 두각을 나타낸다. UI 일부가 여러 번 사용되거나(Button, Panel, Avatar), UI 일부가 자체적으로 복잡한(App, FeedStory, Comment)경우에는 별도의 컴포넌트로 만드는 게 좋다.

📚 Reference

https://ko.reactjs.org/docs/components-and-props.html

profile
Frontend Web/App Engineer

0개의 댓글