🎵 전 회사에서 React를 이용한 프로젝트를 짧게 해본 적이 있지만 처음부터 공부하고 시작한게 아니라 모르는게 많았고, 많이 서툴었다. 지금이라도 기초부터 잡고 처음부터 공부를 하면서 정리 겸 포스팅을 하기로 하였다.
해당 깃허브 에서 보일러플레이트 팩을 다운로드하면 기본 세팅이 되어있다.
터미널에서 npm install 후 npm start를 하면 실행된다.
기본 구조
app : 소스폴더. 보통app아니면 src,source로 폴더명을 지정. 자바스크립트 모듈만 포함하며, 모듈 번들러로 처리되지 않는 정적 에셋(index.html, 이미지 ,css파일 등)은 public폴더에 저장.
public : 정적 파일들을 저장.
- index.html : 번들된 JS를 로드하고 리액트 컴포넌트를 렌더링할 루트(root) div를 제공하는 페이지.
package.json : 터미널에서 npm init 명령하면 해당 파일이 생성. 의존성 관리하는데 사용.
기본적으로 리액트, JSX변환을 위한 Babel 컴파일러,webpack을 포함시킨다.
-scripts에는 명령어 설정
webpack.config.js : 모듈 번들러인 웹팩 구성 파일
실행하기
소스폴더에 있는 App.js를 작성하고 서버를 실행하면 결과를 볼 수 있다.
속성 props : 부모 컴포넌트에서 자식 컴포넌트로 데이터를 전달하는 메커니즘. 속성은 자식 컴포너는 안에서 변경할 수 없으며 부모 컴포넌트가 전달하고 소유한다.
this.props.속성명 으로 가져올 수 있다.
상태 state : 속성은 전달되면 변경 불가. 정적 컴포넌트. state를 사용하여 컴포넌트 전용으로 동작과 상호작용한다. 상태가 변경될 때마다 컴포넌트가 다시 렌더링된다.
this.setState()를 호출해 변경할 수 있다.
ex) App.js에서 해당 데이터를 넘겼을 때 props와 state 사용 예제
{
id:2,
title:"Write some code",
description:"Code along with the samples in the book",
color: "#3A7E28",
status:"todo",
tasks:[
{
id:1,
name:"ContactList Example",
done: true
},
{
id:2,
name:"Kanban Example",
done : false
},
{
id:3,
name:"My own experiments",
done: false
}
]
},
import React,{Component} from 'react';
import CheckList from './CheckList';
class Card extends Component{
constructor(){
super(...arguments);
this.state={
showDetails : false
}
};
render(){
let cardDetail;
if(this.state.showDetails){
cardDetail=(
<div className="card__details">
{this.props.description}
<CheckList cardId={this.props.id} tasks={this.props.tasks} />
</div>
);
};
return(
<div className="card">
<div className="card__title" onClick={()=>
this.setState({showDetails: !this.state.showDetails})}>{this.props.title}
</div>
{cardDetail}
</div>
);
}
};
export default Card;
리액트는 코드안에 인라인으로 XML(HTML까지)을 작성할 수 있게 해주는 JSX라는 자바스크립트 구문 확장이 있다.
필수는 아니지만 표현성이 좋고 일반 자바스크립트 함수 호출로 변환되므로 언어의 의미를 바꾸지 않는단느 장점 때문에 리액트 컴포넌트에서 UI를 정의하는 표준적인 방법이 되었다.
JSX 특성
리액트는 폼을 컴포넌트로서 처리하는 두 가지 방식을 지원.
값이나 확인되는 속성을 가지는 폼 컴포넌트. 제어 컴포넌트의 요소 안에서 렌더링되는 값은 항상 속성의 값을 반영한다. 기본적으로 사용자는 이를 변경할 수 없다.
ex)
<input type="search" value="React" />
this.setState({searchTerm:event.target.value.substr(0,50) })
<textarea value="This is a description" />
<select value="B">
<option value="A">Mobile</option>
<option value="B">Web</option>
</select>
제어 컴포넌트는 리액트의 원칙을 준수하며 그에 따른 혜택을 누린다. 반면 비제어 컴포넌트는 리액트에서 다른 대부분의 컴포넌트가 구성되는 방법과는 다른 패턴이지만 떄로는 사용자 입력 필드를 관리할 필요가 없는 경우가 있다.
특히 큰 폼에서 사용자가 필드 입력하게 한 후 입력이 모두 끝나면 필요한 처리를 모두 할 수 있다.
값을 제공하지 않는 모든 입력 컴포넌트가 비제어 컴포넌트이며, 렌더링되는 요소의 값은 사용자의 입력에 의해 결정된다.
초기값을 설정하고 싶다면 value대신 defaultValue속성 이용
리액트는 개발자가 실제 DOM을 조작하지 않는다. 그런데 컴포넌트에 의해 렌더링 되는 실제 DOM마크업에 접근하고 싶은 경우가 생긴다면 ref를 사용한다. 깔끔한 방법은 아니다.
<input ref="myInput" />
let input = this.refs.myInput;
let valur = input.value;