React 주요 개념
React 주요 개념
JSX
JSX
는 JavaScript를 확장한 문법으로 React Element
를 생성한다.
중괄호를 이용하여 JavaScript 표현식을 넣을 수 있다.
const name = 'React';
const element = <h1>Hello, {name}</h1>;
HTML 어트리뷰트 대신 camelCase를 네이밍 컨벤션으로 사용하며 class
어트리뷰트는 className
으로 작성한다.
<h1 className='hello'> Hello </h1>;
Element
Element
는 React 앱의 가장 작은 단위이며 화면에 표시할 내용을 기술한다.
<div id="root"></div>
이 안에 들어가는 모든 엘리먼트를 React DOM
에서 관리하며 이것을 루트 DOM 노드
라고 부른다.
React 엘리먼트
를 루트 DOM 노드
에 렌더링하려면 둘 다 ReactDOM.render()
로 전달하면 된다.
const element = <h1>Hello</h1>;
ReactDom.render(element, document.getElementById('root'));
일반적으로 엘리먼트는 직접 사용되지 않고 컴포넌트로부터 반환된다.
Props
props
는 속성을 나타내는 데이터로 부모 컴포넌트에서 전달받은 데이터 이다.
'props'는 읽기 전용이므로 컴포넌트에서 자체 props
를 수정해서는 안된다.
Component
Component
를 통해 UI를 재사용 가능한 개별적인 조각으로 나눌 수 있다.
컴포넌트는 함수 컴포넌트
와 클래스 컴포넌트
로 나뉜다.
함수 컴포넌트
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
클래스 컴포넌트
class Welcome extends React.Component {
render() {
return <h1>Hello, {this.props.name}</h1>;
}
}
React 엘리먼트
는 DOM 태그
뿐만 아니라 사용자 정의 컴포넌트
로도 나타낼 수 있다.
const element = <Welcome name="React" />;
React가 사용자 정의 컴포넌트로 작성한 엘리먼트를 발견하면 JSX 어트리뷰트를 해당 컴포넌트에 단일 객체로 전달하는데 이 객체를 props
라고 한다.
컴포넌트 합성
컴포넌트는 자신의 출력에 다른 컴포넌트를 참조할 수 있다.
function App(){
return{
<div>
<Welcome name="Sara" />
<Welcome name="Cahal" />
<Welcome name="Edite" />
</div>
}
}
컴포넌트에 대한 자세한 내용은 Component를 참고
State
state
는 컴포넌트의 상태 를 저장하는 데이터이다.
props
와 다르게 state
는 변경 가능한 값이며 state
가 변경될 경우 뷰에서 관련된 부분만 리렌더링한다.
state
는 기본적으로 클래스 컴포넌트
에서만 사용 가능하며 constructor
에서 state
를 초기화 해주어야 한다.
class Welcome extends React.Component {
constructor(props){
super(props);
this.state = {name: '홍길동'};
}
render() {
return (
<div>
<h1>Hello, {this.state.name}</h2>
</div>
)
}
}
state
는 직접 수정하지 않는다.
// Wrong
this.state.comment = 'Hello';
//Correct
this.setState({comment: 'Hello'});
state
를 직접 바꾸는 방식은 뷰가 리렌더링 되지 않기 때문에 setState
를 이용하여 변경해야 한다.
이벤트 처리
React의 이벤트는 소문자 대신 camelCase
를 사용하며 JSX
를 사용하여 문자열이 아닌 함수로 이벤트 핸들러를 전달한다.
<button onclick="onButtonClick()">
Button
</button>
HTML을 React로 바꾸면 다음과 같다.
<button onClick={onButtonClick}>
Button
</button>
<button onClick={this.onButtonClick}>
Button
</button>
클래스 내의 메소드로 이벤트를 처리할 경우 this
는 기본적으로 바인딩되어 있지 않기 때문에 함수가 실제 호출될 때 this
는 undefined
가 된다.
따라서 콜랙에서 this
가 작동하려면 바인딩 해주어야 한다.
class Button extends React.Component {
constructor(props){
super(props);
this.onButtonClick = this.onButtonClick.bind(this);
}
onButtonClick() {
...
}
render() {
return (
<button onClick={this.onButtonClick}>
Button
</button>
)
}
}
bind
를 호출하기 불편하다면 다음 두가지 방법을 사용할 수 있다.
class Button extends React.Component {
onButtionClick = () => {
...
}
render() {
...
}
}
class Button extends React.Component {
render() {
return (
<button onClick={(e) => this.onButtonClick(e)}}>
Button
</button>
)
}
}
아래 방법은 Button이 렌더링될 때 마다 다른 콜백이 생성되기 때문에 성능 문제가 생길 수 있으니 주의해야 한다.
Key
Key
는 React가 어떤 항목을 변경, 추가, 삭제할지 식별하는 것을 돕는다.
형제 관계 사이에서 고유해야 하고 전체 범위에서는 고유할 필요는 없다.
const numbers = [1, 2, 3, 4, 5];
function ListItem(props){
return <li>{props.value}</li>
}
function NumberList(props){
const listItems = numbers.map((number =>
<ListItem key={number.toString()} value={number} />
);
return (
<ul>
{listItems}
</ul>
);
}
Fragments
Fragments
는 DOM에 별도의 노드를 추가하지 않고 여러 자식을 그룹화할 수 있다.
render() {
return(
<React.Fragment>
<ChildA />
<ChildB />
<ChildC />
</React.Fragment>
// 또는
<>
<ChildA />
<ChildB />
<ChildC />
</>
)
}