React Component에서 다루는 데이터는 props와 state
props
자식 Component가 생성될 때 부모 Component에서 받아온 데이터로 변경이 불가능
자식 Component에서 this라는 키워드를 통해 부모 Component로부터 받은 props를 사용할 수 있음
src/Card.js
// Card.js
import React, { Component } from "react";
class Card extends Component {
render() {
return (
<React.Fragment>
<h3>
이름 : <b>{this.props.name}</b>
</h3>
<h3>
소속 : <b>{this.props.department}</b>
</h3>
<h3>
연락처 : <b>{this.props.phone}</b>
</h3>
<h3>
이메일 : <b>{this.props.email}</b>
</h3>
</React.Fragment>
);
}
}
export default Card;
scr/App.js 수정
// App.js
import React, { Component } from "react";
import Card from "./Card";
class App extends Component {
render() {
return (
<Card
name="jisu"
department="Dev"
phone="010-1234-5678"
email="282532@naver.com"
/>
);
}
}
export default App;
Card가 App의 자식 Component가 되는 것
이 때, 부모Component(App.js) 에서 지정한 name, department, phone, email이
-> 자식Component(Card.js)로 전달되어
Card에서 this.props.name, this.props.department, this.props.phone, this.props.email이 사용
<defaultProps>
- 부모 Component 가 여러 개의 공통된 자식 Component 를 사용할 경우
-> 하지만, 자식 Component에서 공통적으로 사용되는 props와 값이 다양한 props가 있을 수 있다
- 이 경우 , 자식 Component에서 defaultPorps를 이용하여 props의 기본값을 설정해 줄 수 있음
- 기본값 : 부모 Component에서 지정해 줄 경우 지정한 값으로 지정하지 않으면 기본값으로 props가 적용
//Card.js
import React, { Component } from "react";
class Card extends Component {
static defaultProps = {
department : "Dev"
};
render() {
return (
<React.Fragment>
<h3>
이름 : <b>{this.props.name}</b>
</h3>
<h3>
소속 : <b>{this.props.department}</b>
</h3>
<h3>
연락처 : <b>{this.props.phone}</b>
</h3>
<h3>
이메일 : <b>{this.props.email}</b>
</h3>
</React.Fragment>
);
}
}
export default Card;
//App.js
// App.js
import React, { Component } from "react";
import Card from "./Card";
class App extends Component {
render() {
return (
<React.Fragment>
{/* department 생략 */}
<Card name="jisu" phone="010-1234-5678" email="282532@naver.com" />
<hr />
{/* department 포함 */}
<Card
name="joby"
department="Marketing"
phone="010-5678-9123"
email="bob@bob.com"
/>
</React.Fragment>
);
}
}
export default App;
<Functional Component(함수형 컴포넌트)>
- 클래스형 컴포넌트 외 다른 방법으로 컴포넌트 생성
- 단순히 props 받아오는 컴포넌트의 경우 더 간단한 문법으로 사용 가능
- 함수형 컴포넌트는 컴포넌트가 함수이기 때문에 클래스의 특성에서 지닐수 있는 static이나 this 키워드를 사용할 수 없음
- state나 Life Cycle과 관련된 함수를 사용할 수 없습니다.
//Card.js => 함수의 매개변수로 props의 인자들 직접 받음
// Card.js
import React from "react";
const Card = ({ name, department, phone, email }) => {
return (
<React.Fragment>
<h3>
이름 : <b>{name}</b>
</h3>
<h3>
소속 : <b>{department}</b>
</h3>
<h3>
연락처 : <b>{phone}</b>
</h3>
<h3>
이메일 : <b>{email}</b>
</h3>
</React.Fragment>
);
};
// 기본 props 지정(함수형 컴포넌트 사용시 static을 사용불가)
Card.defaultProps = {
department: "Dev"
};
export default Card;
state
- Component 내부에서 생성된 데이터로 변경이 가능
- Component 내부에 state를 class field나 constructor(props) 내부에 정의해서 사용
Method Binding
- 이벤트 처리할 경우 , 임의의 메소드 생성
- 이 때, 해당 메소드에서 state를 변경하기 위해 this 키워드를 사용하려면 메소드에 this를 바인딩 시켜주어야
- constructor(props) 내부에 "this.메소드명 = this.메소드명.bind(this)"를 사용하여 메소드에 this를 바인딩
=> 이 작업이 없을 경우, 이벤트가 발생 시 해당 메소드가 이벤트로 전달되는 과정에서 this와 연결이 끊어져, undefined가 됨
하지만, this 를 메소드로 화살표 함수 표현(Arrow Function Expression)으로 만들 경우,
this 가 풀리는 것에 대해 걱정할 필요가 없기에 method binding 명시적으로 하지 않아도 됨
setState
- 선언된 state 값을 변경하기 위해서는 무조건 this.setState를 사용 /
React 내부에서 setState를 호출하게 되면 자동으로 Component를 리렌더링하게 설계
- 객체로 전달되는 해당 값만 state에서 변경. 전달되지 않은 값은 기존값으로 유지.
state 내부에 객체가 존재하고 그 객체의 특정 인자만 변경하고 싶다면
"객체1: { ..., this.state.객체1, 변경요소: 변경요소 값 }"의 다음과 같은 구조로 작성
=> 그렇지 않으면 객체 자체를 새로 덮어 써버림
전개 연산자(Spread Operator, ...)을 사용하면 기존 내용을 해당 객체에 풀어줌.
- 이 부분은 객체의 depth가 깊어지면 상당히 복잡해지므로 immutable.js나 immer.js를 이용해서 간단화 작업을 하는게 좋음
- 기존의 값을 토대로 새로운 값으로 변경하고 싶을 땐 "값1: this.state.값1" 이런 식으로 처리.
=> this.state를 사용하고 싶지않다면 setState를 화살표 함수로 만들어서 매개변수로 state나 해당 값을 넣어주면 됨.
이 때, 해당 값을 이용할 땐 비구조화 할당(Destructuring Assignment)이라는 문법을 사용합니다.
- render() 함수 내부의 HTML 코드에서 이벤트를 설정할 땐, camelCase로 이벤트명을 적어야 함
- 또한 이벤트 속성의 값으로는 "함수()" 형태가 아닌 "함수명"으로
=> 그렇지 않을 경우 함수 호출이 무한 루프에 빠질수 있습니다. (렌더링 -> 함수 호출 -> setState -> 리렌더링 -> 함수 호출 -> ...)
src/StopWatch.js
// StopWatch.js
import React, { Component } from "react";
class StopWatch extends Component {
// class fields
state = {
sec: 0,
buttonFlag: true,
intervalFunction: null
};
// stop watch 로직
timer = () => {
// 비구조화 할당 사용( { sec } 부분 )
this.setState(({ sec }) => ({
sec: sec + 1
}));
};
// start 버튼 클릭
start = () => {
this.setState({
sec: 0,
buttonFlag: false,
intervalFunction: setInterval(this.timer, 1000)
});
};
// stop 버튼 클릭
stop = () => {
clearInterval(this.state.intervalFunction);
this.setState({
buttonFlag: true
});
};
render() {
return (
<React.Fragment>
<h1>Stop Watch</h1>
<div>
<b>{this.state.sec}</b>
<span>초</span>
{this.state.buttonFlag ? (
<button onClick={this.start}>start</button>
) : (
<button onClick={this.stop}>stop</button>
)}
</div>
</React.Fragment>
);
}
}
export default StopWatch;
src/App.js
// App.js
import React, { Component } from "react";
import StopWatch from "./StopWatch";
class App extends Component {
render() {
return <StopWatch />;
}
}
export default App;
'Language Study > React' 카테고리의 다른 글
4. Life Cycle API (0) | 2019.11.26 |
---|---|
2. JSX (0) | 2019.11.26 |
1. 준비사항 (0) | 2019.11.26 |