컴포넌트를 만들 때 재사용이 가능할 만한 부분이 있다. 그런 것은 여러 조각으로 나눠놓으면 재사용이 가능할 뿐더러 가독성도 좋아진다. 컴포넌트의 개념을 살펴보자.
컴포넌트를 정의하는 가장 간단한 방법은 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')
);
위의 예시는 다음과 같은 일이 일어난다.
<h1> Hello, Sara </h1>
엘리먼트를 반환한다.
4. React DOM은
<h1> Hello, Sara </h1>
엘리먼트와 일치하도록 DOM을 효율적으로 업데이트 한다.
주의 : 사용자 정의 컴포넌트 이름은 항상 대문자로 시작한다.
React 는 소문자로 시작하는 컴포넌트는 DOM 태그로 처리한다.
JSX 안에서 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="<3" />
<MyComponent message={'<3'} />
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 에 대한 이론은 살펴보았으니 프로젝트에서 테스트해보고 적용해보자.