Component 추출하기
function Comment(props) {
return (
<div className = "Comment">
<div className = "UserInfo">
<img className = "Avatar"
src = {props.author.avatarUrl}
alt = {props.author.name}
/>
<div className = "UserInfo-name">
{props.author.name}
</div>
</div>
<div className = "Comment-text">
{props.text}
</div>
<div className = "Comment-date">
{formatDate(props.date)}
</div>
</div>
);
}
위 코드는 작성자(Avatar), 글(Comment), 날짜(Date)를 prop으로 받는다. 하지만 위 코드는 컴포넌트들이 다 짬뽕되어있기 때문에 좋은 코드라고 할 수 없다. 좋은코드가 되려면 컴포넌트를 최대한 잘게 쪼개야하고, 그 컴포넌트들의 재사용성을 높여야 한다.
function Avatar (props) {
return (
<img className = "Avatar"
src = {props.author.avatarUrl}
alt = {props.author.name}
/>
);
}
쪼개진 Avatar Component
function UserInfo(props) {
return (
<div className="UserInfo">
<Avatar user={props.user} />
<div className="UserInfo-name">
{props.user.name}
</div>
</div>
);
}
UserInfo Component
function Comment(props) {
return (
<div className="Comment">
<UserInfo user={props.author} />
<div className="Comment-text">
{props.text}
</div>
<div className="Comment-date">
{formatDate(props.date)}
</div>
</div>
);
}
UserInfo, Avatar Component가 쪼개져서 간략해진 Comment Component
Props에 관하여
function sum (a, b) {
return a + b;
}
위의 함수는 받아온 props 값을 바꾸지 않은 순수함수
이다. 그리고 같은 입력값에 대한 항상 같은 결과를 출력해냅니다.
function foo (account, amount) {
account.total -= amount;
}
다음과같이 props가 변하는 함수를 비순수 함수라고 합니다.
react는 props의 측면에서 봤을때 순수함수처럼 동작해야한다.
그렇다면 props가 고정된 상태에서 react는 어떻게 동적으로 움직일까? state
가 그 답이 될 수 있다.
State
-
state는 props와 비슷하다.
-
하지만 props와는 다르게 private한 특성을 가지고 있다.
-
Component에 의해 완전히 통제된다.
class Clock extends React.Component {
constructor(props) {
super(props);
this.state = {date: new Date()};
}
render() {
return (
<div>
<h1>Hello, world!</h1>
<h2>It is {this.state.date.toLocaleTimeString()}.</h2>
</div>
);
}
}
ReactDOM.render(
<Clock />,
document.getElementById('root')
);
위 코드를 살펴보면
-
props를 state에 넘겨주는 과정이 있다.
-
기존 render에 props가 들어가던 자리에 이젠 state가 들어간다.
state를 정의 하는법
classfields문법을 사용한다.
class Counter extends Component {
constructor (props) {
super(props);
this.state = {
number : 0
}
}
}
위코드의 super(props);
의 이유는 Component를 상속했기 때문에 기존에 있던 props를 미리 실행하고 state를 설정하기 위함이다.
동적 인자인 state
의 값을 바꾸기 위해선 this.setState
를 무조건 거쳐야한다.
state = {
number : 0,
foo : 'bar'
}
위의 코드처럼 state가 선언되었다고 할 때 이를 바꿔주기 위해선 this.setState({ number : 1 })
을 해주면 된다.
그러나 객체안의 객체
state = {
number : 0,
foo : {
bar : 0,
foobar : 1
}
}
라면 this.setState({foobar : 2})
로 foobar
을 2로 바꿀 수는 없다. 따라서 immutable.js
또는 immer.js
를 사용하거나 foo 객체 안에 ...this.state.foo
라고 this를 연결시켜주어야 한다.
state의 비구조화 할당
const { number } = this.state;
this.setState({
number: number + 1
});
이런식으로 하면 state에 함수할당이 더 쉽게 가능하다.
이벤트 설정
react 이벤트 설정시 주의사항
-
이벤트의 이름은 무조건 camelCase로 해주어야한다.(ex onClick)
-
이벤트에 전달해주는 값은 함수여야 한다. (만든 메소드가 아닌 함수여야 한다는 것)
<button onClick={this.handleIncrease}>+</button> // 옳은 방식
<button onClick = {this.handleIncrease()}>+</button> // 틀린 방식 랜더링할때마다 이 함수가 호출되서 무한반복에 빠져버림.
Ghost