props는 사용자가 컴포넌트를 사용하는 입장에서 중요한 것이고, state는 props의 값에 따라서 내부의 구현에 필요한 데이터라고 생각할 수 있다. 컴포넌트의 기본적인 동작을 바꾸고 싶을 때 사용자에게 제공하는 것이 props이다. 이를 통해 사용자는 컴포넌트를 조작할 수 있게 된다. 그리고 컴포넌트 내부적으로 사용되는 것을 state라고 한다.
리액트가 컴퍼넌트를 만들고 그 컴퍼넌트가 좋은 부품이 되기 위해서는 그 컴퍼넌트를 사용하는 외부의 props와 그 props에 따라서 그 컴퍼넌트를 실제로 구현하는 내부의 state가 철저하게 분리되어 있어야 한다.
어떤 컴퍼넌트가 실행될 때 렌더 함수보다 먼저 실행 되면서 그 컴퍼넌트를 초기화 시켜주고 싶은 코드는 컨스트럭터 안에 코드를 작성한다.
리액트에서는 스테이트의 값이 바뀌면 그 스테이트를 가지고 있는 컴포넌트의 렌더 함수가 호출되기로 약속되어 있다. 그러면 그 렌더 함수 안의 하위 컴포넌트도 각자의 렌더 함수를 가지고 있으므로 그 안의 코드들도 모두 호출되는 것이다. 그 결과로 화면은 다시 그려지게 된다. 즉 스테이트나 프롭스의 값이 바뀌면 화면은 다시 그려지게 된다.
<h1>
<a href="/" onClick={function(e){
e.preventDefault();
//this.state.mode = 'welcome';
this.setState({
mode: 'welcome'
});
}.bind(this)}> {this.state.subject.title}</a>
</h1>
이벤트를 설치하면 이벤트가 실행될 때, 즉 함수가 호출될 때 함수의 첫 번째 매개변수 값으로 e라고 하는 객체를 주입해주기로 약속되어 있다. e 객체 안에는 이벤트를 핸들링할 수 있게끔 하는 정보들이 담겨있다. 예를 들어 e.preventDefault()에서 preventDefault라는 함수는 e라는 객체에 속해있다. 이 함수는 그 이벤트가 발생한 태그의 기본적인 동작을 못하게 막는 역할을 한다. a태그는 클릭이 되었을 때 새로고침을 하는 동작이 기본으로 깔려있다.
여기서 주의할 것이 있다. 이벤트가 호출되었을 때 실행되는 함수 안에서는 this의 값이 컴포넌트 자신을 가리키지 않고 아무 값도 세팅되어있지 않다. 이럴 때는 함수가 끝난 직후에 bind(this)를 추가해주어야 한다. 그러면 함수 안에서 this가 이 컴포넌트를 가리키게 된다.
그리고 this.state.mode로 state의 값을 바꾸어서는 리액트에서 읽히지 않는다. this.setState({mode:'welcome'})로 해야한다. 이 뜻은 setState 함수를 호출할 때 mode를 welcome으로 바꾸고 싶다라는 의미이다.
var obj = {name:'egoing'};
function bindTest() {
console.log(this.name);
}
bindTest(); //undefined
var bindTest2 = bindTest.bind(obj);
bindTest2(); // egoing
bindTest 함수를 호출했을 때 this값으로 obj를 가리키고 싶다. 하지만 undefined가 나올 것이다. bind 함수에 obj라는 첫 번째 인자를 주면 bindTest 함수의 블럭 안에서 this는 obj가 되는 새로운 함수가 만들어 진다.
App이라는 컴포넌트가 생성될 때 최초로 가장 먼저 실행되는 컨스트럭터라는 함수 안에서는 state 값을 수동적으로 바꿀 수 있다. 하지만 이미 컴포넌트의 생성이 끝난 다음에 동적으로 스테이트 값을 바꿀 때는 그렇게 해서는 안되고 setState를 써서 변경하고 싶은 값을 객체형태로 전달해서 바꿔야 한다.