[TIL]react(2) - Props과 Component

Violet Lee·2020년 11월 19일
0

Component

함수 컴포넌트, 클래스 컴포넌트 두가지 종류로 사용할 수 있음.

  • 함수 컴포넌트
function app(props){
...
<div>
<Tweet></Tweet> //사용자 정의 컴포넌트 Tweet
</div>
...
}
//이 함수를, react 컴포넌트 라고 부른다.
function Tweet(){
	return <div>트윗 컴포넌트</div>
}

위 예제의 함수는, 데이터를 가진 하나의 'props(속성을 나타내는 데이터)'객체 인자를 받은후,
react 엘리먼트를 반환한다. 즉, 이 함수는 유효한 react 컴포넌트이다.
그리고 이 컴포넌트는 js함수이기 때문에, '함수 컴포넌트'라고 부른다.


  • 클래스 컴포넌트(ES6)
class app extends React.Component{
	render(){
    	return <div>트윗 컴포넌트 이름 : {this.props.name}</div>
    }

}

컴포넌트 렌더링

React 엘리먼트들은 두 가지로 나타낼 수 있다.

  1. 하나의 DOM태그로 묶어 나타내기.
let el = <div />;
  1. 사용자 정의 컴포넌트로 나타내기.
let el = <Tweet id="pioneerJ" />;

JSX문법으로 작성된 엘리먼트는 하나의 엘리먼트로 묶여서 새 객체로 반환된다.
위에서 작성한 Tweet 컴포넌트를 App 컴포넌트안에 담으면

//App.js
import React from 'react'; //react 불러오기

function App() {
  return (
    <div>
      <Tweet />
    </div>
  );
}

export default App; //App 컴포넌트 내보내기

이제 App.js를 index.js를 만들어서 Tweet 컴포넌트를 내보내려고 한다.

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

ReactDOM.render(<App />, document.getElementById('root'));
//브라우저에 있는 실제 DOM내부에 리액트 컴포넌트를 렌더링하겠다는 것을 의미한다.
//그리고 렌더링하여 붙일 리액트 컴포넌트는 id가 root인 dom을
//선택하고 있다.

//-> 즉 리액트 컴포넌트가 렌더링될때에는 , 렌더링된 결과물이 위 div내부에
//다시 렌더링이 되는것이다.
reportWebVitals(); //아직 모름 ㅠㅠ

👉컴포넌트 작성 규칙

  • 컴포넌트 이름은 항상 대문자로 시작한다.
    : react는 소문자로 시작하는 이름의 컨포넌트를, DOM태그로 처리해버린다.

컴포넌트 합성

: 예를 들어 tweet을 여러 번 렌더링하는 App 컴포넌트를 만들 수 있는것이다.

function Tweet(props) {
  return <h1>Hello, {this.props.id} !</h1>;
}

function App() {
  return (
    <div>
      <Tweet id='pioneerJ' />
      <Tweet id='pioneerK' />
      <Tweet id='pioneerL' />
    </div>
  );
}

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

컴포넌트 추출

ex) 중첩구조로 이루어진 comment 컴포넌트를, 몇 가지 컴포넌트를 추출하여 재사용성을 증가시켜보자.

//이 컴포넌트는 author(객체), text(문자열), date(날짜)를 각각 props로 받은 후,
//SNS 사이트의 comment를 나타내는 컴포넌트이다.
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>
    );
}

- Avatar 추출하기

function Avatar(props){ //-> <Avatar user = {props.author} />
  return (
    <img className='Avatar' 
         src={props.user.avatarUrl}
	//**props의 이름은, '사용될 컴포넌트 자체의 관점'에서 짓는것이 좋다고 한다.
	 alt={props.user.name}
    />
  );
}

👉 Avatar는, 자신이 Comment안에서 렌더링 된다는 사실을 알 필요없다.
때문에, Avatar 입장에서 볼 때로 이름을 바꿔줄 수 있다.
'author' 속성이름을, 일반화된 'user'로 변경하여 사용하였다.

Avatar 컴포넌트를 사용자 정의 컴포넌트로 만들어서 다시 Comment컴포넌트 안에 넣어보았다.

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>
    );
}

이제 Avatar를 추출 함으로써, Comment 컴포넌트가 한층 더 가벼워보이는 것을 볼 수있다.
계속해서 Avatar가 들어있는 UserInfo 부분도 스리슬쩍 빼 보겠다.

- UserInfo 추출하기

function UserInfo(props){ //-> <UserInfo user = {props.author} />
  return (
    <div className='UserInfo'>
      <Avatar user={props.user} />
      <div className='UserInfo-name'>
        { props.user.name }
      </div>
    </div>
  );
}

UserInfo 컴포넌트 또한 사용자 정의 컴포넌트로 만들어서 다시 Comment컴포넌트 안에 넣어보았다.

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, Comment ..)에 좋다!

Props : 즉, component의 인자라고 생각하면 된다.

👉props를 다루는 규칙

  • 함수 컴포넌트 이건, 클래스 컴포넌트 이건, 모두 컴포넌트의 자체 props를 수정할 수 없다.

  • 컴포넌트 추출 과정 시, 이 props의 속성이름을 해당 props를 사용하는 관점에서 변경이 가능하다.

  • 모든 React 컴포넌트는, 자신의 props를 다룰 때 반드시 *순수 함수처럼 동작해야 한다.


*순수 함수

다음은 순수 함수와, 순수 함수가 아닌 예제이다.

순수 함수		        순수 함수가 아님.
function sum(a, b) { 	function withdraw(account, amount) {
    return a + b;		account.total -= amount;
}			}

=> 입력값을 바꾸려 하지 않고, 항상 동일한 입력값에 대해 동일한 결과를 반환하기 때문
순수 함수라고 부른다.

=> 그에 반해, 오른쪽 예제는 자신의 입력값을 변경하기 때문에 순수 함수가 아니다.

profile
예비개발자

0개의 댓글