5/14 TIL

kind J·2022년 5월 14일
0
post-thumbnail

컴포넌트를 만들 때 재사용이 가능할 만한 부분이 있다. 그런 것은 여러 조각으로 나눠놓으면 재사용이 가능할 뿐더러 가독성도 좋아진다. 컴포넌트의 개념을 살펴보자.

컴포넌트를 정의하는 가장 간단한 방법은 JS 함수를 작성하는 것이다.

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

위의 함수는 데이터를 가진 하나의 "props" 객체 인자를 받은 후 React 엘리먼트를 반환하므로 유효한 React 컴포넌트이다. 이 컴포넌트는 JS 함수이기 떄문에 "함수 컴포넌트"라고 한다.

ES6 class 를 사용해서 컴포넌트를 정의할 수도 있다.

class Welcome extends React.Component {
  render() {
    return <h1>Hello, {this.props.name}</h1>;
  }
}

컴포넌트 렌더링

이전에는 DOM 태그만을 사용해 React 엘리먼트를 나타냈다.

const element = <div/>

React 엘리먼트는 사용자 정의 컴포넌트로도 나타낼 수 있다.

const element = <Welcome name ="Sara"/>

React 가 사용자 정의 컴포넌트로 작성한 엘리먼트를 발견하면 JSX 어트리뷰트와 자식을 해당 컴포넌트에 단일 객체로 전달한다. 이 객체를 "props" 라고 한다.

"Hello, yunji" 를 랜더링 하는 예시가 있다.

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

const element = <Welcome name="sara" />
ReactDOM.render(
	element,
    document.getElementById('root')
);

위의 예시는 다음과 같은 일이 일어난다.

  1. 엘리먼트로 ReactDOM.render() 를 호출한다.
  2. React는 {name: 'Sara'}를 props로 하여 Welcome 컴포넌트를 호출한다.
  3. Welcome 컴포넌트는 결과적으로
<h1> Hello, Sara </h1>

엘리먼트를 반환한다.
4. React DOM은

<h1> Hello, Sara </h1>

엘리먼트와 일치하도록 DOM을 효율적으로 업데이트 한다.

주의 : 사용자 정의 컴포넌트 이름은 항상 대문자로 시작한다.
React 는 소문자로 시작하는 컴포넌트는 DOM 태그로 처리한다.

JSX 안에서 props 사용

JSX 안에서 props 를 사용하는 방법은 여러가지가 있다.

JS Expressions as Props

아래와 같이 JS 표현을 {} 안에 넣어서 JSX 안에서 prop으로 사용할 수 있다.

<MyComponent foo={1 + 2 + 3 + 4} />

MyComponent 의 props.foo 의 값은 1+2+3+4 의 표현식이 계산되기 때문에 10 이다.
if 문과 for 반복문은 JS 표현식이 아니기 때문에 JSX 안에서 그대로 사용할 수 없다.

표현식
값으로 평가될 수 있는 문, 표현식이 평가되면 새로운 값을 생성하거나 기존 값을 참조한다.

하지만 아래와 같이 JSX 밖의 주변 코드에서 사용할 수 있다.

function NumberDescriber(props) {
	let description;
    if(props.number %2 == 0){
    	description = <strong>event</strong>;
    } else{
    	description = <i>odd </i>
    }
    
    return <div>{props.number} is an {description} number </div>
}

문자열 리터럴

문자열 리터럴은 prop으로 넘겨줄 수 있다. 아래 두 JSX 표현은 동일한 표현이다.

<MyComponent message="hello world" />

<MyComponent message={'hello world'} />

문자열 리터럴을 넘겨줄 때 그 값은 HTML 이스케이프 처리가 되지 않는다. 따라서 아래 두 JSX 표현은 동일하다.

<MyComponent message="&lt;3" />

<MyComponent message={'<3'} />

Props 의 기본값은 "True"

props 에 어떤 값도 넘기지 않을 경우 기본 값은 true 이다.
아래 두 JSX 표현은 동일한 표현이다.

<MyTextBox autocomplete />

<MyTextBox autocomplete={true} />

일반적으로 props 에 대한 값을 전달하지 않는 것을 권장하지 않는데 이는 ES6 객체 리터럴 방식과 헷갈릴 수 있기 때문이다.

속성 펼치기

props 에 해당하는 객체를 이미 가지고 있다면, ... 을 전개 연산자로 사용해서 전체 객체를 그대로 넘겨줄 수 있다. 아래의 두 컴포넌트는 동일하다.

function App1() {
	return <Greeting firstName="Ben" lastName="Hector" />
}

function App2() {
	const props = {firstname : 'Ben', lastName : 'Hector'}
	return <Greeting {...props} />
}

컴포넌트가 사용하게 될 특정 prop을 선택하고 나머지 prop 은 전개 연산자를 통해 넘길 수 있다.

const Button = props => {
	const {kind, ...other} = props;
    const className = kind === "primary" ? "primaryButton" : "SecondaryButton" ;
    return <button className={className} {...other} />
};

const App = () => {
	return (
    	<div>
        	<Button kind="primary" onclick{() => console.log("clicked!"}>
            Hello world!
            </Button>
        </div>
    )
}

위의 예시를 보면 kind props은 소비되고 DOM button element 에 넘겨지지 않는다. 다른 모든 prop 은 ...other 객체를 통해서 넘겨지고 이 컴포넌트를 유연하게 만든다. onClick 과 children prop 으로 넘겨지는 것을 볼 수 있다.

전개 연산자연 유용하지만 불필요한 prop을 컴포넌트에 넘기거나 유효하지 않은 HTML 속성들을 DOM 에게 넘기기도 한다. 꼭 필요할 때만 사용하는 것이 좋다.

추가설명

rest

const numbers = [0, 1, 2, 3, 4, 5, 6];

const [one, ...rest] = numbers;

console.log(one); //0
console.log(rest); //[1,2,3,4,5,6]

props 에 대한 이론은 살펴보았으니 프로젝트에서 테스트해보고 적용해보자.

Reference

https://learnjs.vlpt.us/useful/07-spread-and-rest.html

profile
프론트앤드 개발자로 일하고 있는 kind J 입니다.

0개의 댓글