- JSX -> React.createElement(component, props, ...children)으로 변환되는 문법적 설탕
<MyButton color="blue" shadowSize={2}>
Click Me
</MyButton>
<div className="sidebar" />
React.createElement(
MyButton,
{color: 'blue', shadowSize: 2},
'Click Me'
)
React.createElement(
'div',
{className: 'sidebar'}
)
React Element의 타입 지정
- JSX 태그의 첫 부분은 React Element의 타입 결정
- JSX 태그는 같은 이름을 가진 변수들을 직접 참조함 -> 같은 스코프 내에 참조할 컴포넌트가 있어야 함
- JSX가 React.createElement를 호출하는 코드로 컴파일 되기 때문에 리액트 라이브러리 역시 JSX 코드와 같은 스코프내에 존재해야 함
html의 script 태그로 리액트를 불러오면 전역변수로 존재하기 때문에 불러올 필요가 없음
import React from 'react';
import CustomButton from './CustomButton';
function WarningButton() {
return <CustomButton color="red" />;
}
- JSX 타입 내에서 점 표기법을 통해 특정한 컴포넌트를 지정할 수 있음
import React from 'react';
const MyComponents = {
DatePicker: function DatePicker(props) {
return <div>Imagine a {props.color} datepicker here.</div>;
}
}
function BlueDatePicker() {
return <MyComponents.DatePicker color="blue" />;
}
- 소문자로 시작하는 컴포넌트는 내장 컴포넌트로 간주하기 때문에 컴포넌트를 작성할때는 대문자로 시작하는 이름을 지어야 함
import React from 'react';
function Hello(props) {
return <div>Hello {props.toWhat}</div>;
}
function HelloWorld() {
return <Hello toWhat="World" />;
}
- React Element 타입에 일반적인 표현식을 사용할 수 없기 때문에 다른 변수에 먼저 값을 지정한 다음 사용해야 함
import React from 'react';
import { PhotoStory, VideoStory } from './stories';
const components = {
photo: PhotoStory,
video: VideoStory
};
function Story(props) {
const SpecificStory = components[props.storyType];
return <SpecificStory story={props.story} />;
}
JSX 안에서의 prop 사용
- 자바스크립트 표현을 {} 안에 넣어서 JSX 안에서 prop으로 사용 가능
- if, for문 등은 표현식이 아니기 때문에 JSX안에서 사용 불가능
- JSX 밖의 코드 주변에서 값을 가져와야 함
function NumberDescriber(props) {
let description;
if (props.number % 2 == 0) {
description = <strong>even</strong>;
} else {
description = <i>odd</i>;
}
return <div>{props.number} is an {description} number</div>;
}
<MyComponent message="<3" />
<MyComponent message={'<3'} />
- prop에 어떠한 값도 넘기지 않으면 기본값은 true로 설정됨
<MyTextBox autocomplete />
<MyTextBox autocomplete={true} />
- prop에 넘길 객체를 이미 정의해 두었다면 spread 연산자로 전개 가능
function App1() {
return <Greeting firstName="Ben" lastName="Hector" />;
}
function App2() {
const props = {firstName: 'Ben', lastName: 'Hector'};
return <Greeting {...props} />;
}
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>
);
JSX에서 자식 다루기
- 여는 태그와 닫는 태그가 있는 JSX에서 두 태그 사이 내용은 props.children이라는 특수한 prop으로 넘겨짐
- 문자열이 들어오게 되면 props.children은 문자열이 됨
<MyComponent>Hello world!</MyComponent>
<div>This is valid HTML & JSX at the same time.</div>
<div>
Hello
World
</div>
<div>
Hello World
</div>
- 자식 요소로 다른 JSX 요소가 들어올수도 있음
<div>
Here is a list:
<ul>
<li>Item 1</li>
<li>Item 2</li>
</ul>
</div>
- 자식 요소로 자바스크립트 표현식도 들어올 수 있음
function Item(props) {
return <li>{props.message}</li>;
}
function TodoList() {
const todos = ['finish doc', 'submit pr', 'nag dan to review'];
return (
<ul>
{todos.map((message) => <Item key={message} message={message} />)}
</ul>
);
}
function Repeat(props) {
let items = [];
for (let i = 0; i < props.numTimes; i++) {
items.push(props.children(i));
}
return <div>{items}</div>;
}
function ListOfTenThings() {
return (
<Repeat numTimes={10}>
{(index) => <div key={index}>This is item {index} in the list</div>}
</Repeat>
);
}
- null, undefined, false, true는 child로 들어올 수 있지만 렌더링 되지는 않음
<div />
<div></div>
<div>{false}</div>
<div>{null}</div>
<div>{undefined}</div>
<div>{true}</div>
<div>
{showHeader && <Header />}
<Content />
</div>
<div>
{props.messages.length &&
<MessageList messages={props.messages} />
}
</div>