React 는 View(html tag 의 조합) 를 만들기 위한 것이다. (물론 디테일은 다르다. 이것과 관련된 이야기는 여기서 하자.)그런데 이 view 를 좀 더 동적으로 변경시킬 수 있게 하기 위해 이 component 가 변수를 갖게 됐다. 여기서는 이 변수의 의미를 살펴보면서 이 변수를 이용해서 어떻게 React 를 사용하는지 살펴보자.
prop, state 의 차이
prop 은 한 번 지정하면, 바꾸지 않을 값이고,state 는 계속해서 바꾸는 값이다.
의미를 생각하면 쉽다. property(속성) 은 그 객체가 가진 고유한 속성이니까 바뀌지 않는 값이며, state(상태) 는 그 객체의 현재 기분같은 것이라서 바뀔 수 있는 값이다.
댓글의 '최민규' 님이 아래 처럼 이야기 해주셨다. 개인적으로도 훨씬 이해가 잘 되는 설명같다.
그런데 prop 으로 지정한 값이 state 에 initial value 로 동작하길 원하는 경우도 있다. 예를 들면 checkbox 의 값이 처음에는 parent component 의 상태로 값이 결정되지만, 추후에는 checkbox 에 대한 click event 로 결정된다. 이 경우에 componentWillReceiveProps 함수를 이용해서 처음prop 으로 넘어온 값을 state 에 다시 할당해 주는 과정을 거치면 된다.(참고)
- props는 상위 컴포넌트에서 전달하는 것 --> 하위 컴포넌트에서 수정을 못한다.
- state는 해당 컴포넌트가 자기 자신의 상태를 제어하기 위한 값 --> 수정할 수 있는 것
prop
<Shop owner="Me">Grocery</Shop>
위의 code 에서 Shop 의 props 은 아래와 같이 생성된다.
props = { owner : "Me", children : "Grocery" }
간단하게 생각하면, prop 은 parameter 같은 녀석이다. html element 에서는 이것을 속성(attribute) 라고 부르지만, 함수로 생각하면 parameter 이다. 이 녀석이 React 에서는 property 가 되는 것이다. 부르는 호칭만 다르지, 의미는 대동소이하다.
state
React 에서 이야기하는 state 는 필자의 의견으로는 check box 를 연상하는 것이 좋은 방법이 될 듯 하다. 우리가 check box 를 click 하면 어떤 상태(state) 인지를 표시하는 것이 되고, 이것을 기반으로 화면이 변화가 생긴다. 이렇게 값이 변하는 속성(property) 이 state 라고 보면 된다.좀 더 정확한 설명은 ref. 1을 확인하자.
prop 관련 함수
getDefaultProps
getInitialState 와 같은 역할을 한다.State 관련 함수
state 와 관련해서 몇가지 함수를 살펴보자.getInitialState
내가 만든 component 에 초기 state 값을 주고 싶다면 getInitialState 를 정의하면 된다. react.js 는 처음에 initialState 를 set 하기 위해 getInitialState() 를 호출하기 때문이다. 사용법은 아래 코드를 참고하자.setState
이렇게 생성된 state 값을 변경할 때는 setState({}) 를 사용하면 된다.DOM 관련 API
componentDidMount
이녀석은 여기서 component (html tag의 조합이라 보면 된다.) 를 dynamic 하게 만들기 때문에, 이녀석의 DOM 이 만들어진 이후에 작업을 해야 할 일이 있을 수 있다. 그 때 사용하면 된다. mount 됐다는 이야기가 document 에 attach 된 상태는 아니라고 한다. 그냥, initialized and rendered 라고 한다.
var CommentBox = React.createClass({ getInitialState: function() { return { data: [] }; }, componentDidMount: function() { this.setState({ data: "testtestest" }); this.loadCommentsFromServer(); return setInterval(this.loadCommentsFromServer, this.props.pollInterval); }, render: function() { return ( <div className="commentBox"> Hello, world! <h1>Comments</h1> <CommentList data={this.state.data}/> <CommentForm onCommentSubmit={this.handleCommentSubmit}/> </div> ); } });
- Mounting: componentWillMount
- Mounting: componentDidMount : 한번만 호출된다. 처음 render 후, mount 될때
- Updating: componentWillReceiveProps : 그리고, props 가 변할 때 setState() 를 호출해서 state 를 변경해야 하는 경우라면 여기를 이용하자.
이 함수에서 setState() 를 호출해도 render 를 다시 호출하지 않는다. 그러므로 setState() 를 사용하려면 여기서 해야 한다. - Updating: shouldComponentUpdate : update (render() 호출)를 하는지 여부를 결정할 수 있다. 관련해서는 ref. 3 를 읽어보자.
- Updating: componentWillUpdate
- Updating: componentDidUpdate
- Unmounting: componentWillUnmount
ref 속성 : refs
React 가 component 를 만드는 것을 해주고, 이것을 동적으로 다룰 수 있게 해준다. 그런데, 내가 만든 component 가 여러개의 element 로 이뤄졌을 경우, 이 녀석들을 구분해서 접근할 수 있어야 한다. 이런 역할을 해주는 것이 ref attribute 이다.ref 속성을 이용해서 element 를 우리가 만든 component 에서 바로 접근할 수 있도록 해준다. 아래 예제를 참고하자.
ReactDOM.findDOMNode
ref="author" 라고 하면, this.refs.author 로 input instance 를 접근할 수 있게 해준다. 실질적인 HTML DOM 은 React.findDOMNode 함수를 통해 접근해야 한다.CommentForm = React.createClass( handleSubmit : (e)-> e.preventDefault() author = ReactDOM.findDOMNode(this.refs.author).value.trim() text = ReactDOM.findDOMNode(this.refs.text).value.trim()
if not text or not author
return
# TODO: send request to the server
ReactDOM.findDOMNode(this.refs.author).value = ''
ReactDOM.findDOMNode(this.refs.text).value = ''
return render : ()-> `( <form className="commentForm" onSubmit={this.handleSubmit}> <input type="text" placeholder="Your name" ref="author" /> <input type="text" placeholder="Say something..." ref="text" /> <input type="submit" value="Post" /> </form> )` )
propTypes
이 녀석은 type 검사 같은 것을 해준다. 뭐 필요없을 수도 있지만, 개인적으로 필요하다고 생각하는 녀석이다.var MyComponent = React.createClass({ propTypes: { children: React.PropTypes.element.isRequired }, render: function() { return ( <div> {this.props.children} // This must be exactly one element or it will warn. </div> ); } });
child Component
만약 아래처럼 child component 를 갖는 경우에 parent 에 이녀석을 처리하려면 this.props.children 을 이용하면 된다. 참고로 child 가 한개면 그냥 component 를 주고, 여러개 이면, array 를 넘겨준다.<MyParent> <MyChild1/> <MyChild2/> </MyParent>
React.PureComponent
ref. 3 을 보면 나오는데, PureComponent 는 state 나 prop 이 변경된 때에만 render() 를 호출하고 싶은 component 를 만들 때 쓰면 된다.
이녀석은 React.Component 와 같다. 그런데, 단지 render() 를 호출하기전에 state 나 prop 의 변경이 있는지 여부를 보고, 변경된 사항이 있으면 render() 를 호출한다. 그런데 이 비교를 대충하는 것이니(shallow comparison), 실제로 detail 한 비교를 하려면 shouldComponentUpdate 를 직접 작성해야 한다고 한다. 자세한 사항은 ref. 3을 참고하자.
props는 상위 컴포넌트에서 전달하는 것이기 때문에 하위 컴포넌트에서 수정을 못하는 것이고 state는 해당 컴포넌트가 자기 자신의 상태를 제어하기 위해 수정할 수 있는 것이라는 표현이 더 정확한거 같네요. propTypes는 해당 컴포넌트가 받을 수 있는 props에 대한 유효성 검사도 실행할 수 있을 뿐만 아니라 어떤 props가 전달되는지도 확인가능하므로 props가 전달되는 컴포넌트는 다 작성해주시는게 좋습니다.
답글삭제네, 좋은 답변 감사합니다. 본문에도 적어넣었습니다.
삭제