React.js를 사용한지 어느덧 10개월이 된것 같다.
잠시 3개월동안 프리로 일한 곳에서 세달동안 일하면서,
처음으로 만져본 React.js.
DOM요소를 직접 컨트롤 하는 jQuery방식이 몸에 배었고,
jQuery적인 발상으로 로직을 짜서 작업을 해왔기 때문에,
React로 작업했던 그 세달이 너무나 고통스러웠다.
지금은 jQuery도 많이 잊어버렸고, react가 훨씬 편하다.
React는 SPA(Single Page Application) 라이브러리이다.
하나의 HTML 파일에서 여러 컴포넌트를 mount/unmount 하면서
유연하게 웹어플리케이션 운용을 가능하게 한다.
그 중심에 있는 것이 바로 state 와 props 이다.
State
import React from "react";
export default class App extends React.Component{
constructor(props){
super(props);
this.state={
name:"albatro33"
}
}
render(){
return(
<>
<h1>hi my Name is {this.state.name}</h1>
</>
)
}
}
위와 같이 기본적인 컴포넌트를 작성하였을 때,
state라는 object의 값을 통해, 여러 조작이 가능하다.
state는 말그대로 상태이다.
state는 컴포넌트 내부에 존재하는 상태값으로써,
React 컴포넌트 안에서 조작할 수 있는 기본적이면서 매우 중요한 요소이다.
현재 App 이라는 컴포넌트의 name 이라는 상태값은 "albatro33"이라는 문자열이다.
import React from "react";
export default class App extends React.Component{
constructor(props){
super(props);
this.state={
name:"albatro33"
}
}
handleChange = e => {
const name = e.target.value;
this.setState({
name
});
}
render(){
return(
<>
<h1>hi my Name is {this.state.name}</h1>
<input value={this.state.name} onChange={this.handleChange} />
</>
)
}
}
위 코드에는 input이 존재한다.
input의 value는 state의 name 이며, onChange이벤트 발생 시, handleChange라는 함수를 호출한다.
handleChange에 설정한 대로, event target(input)의 value값으로 state를 변경해준다.
setState는 state값을 변경해주는 react의 기본 내장함수이다.
input의 값이 변경되면, state의 name에 저장된 문자열도, 입력하는 대로 변경된다.
동시에 h1태그에 호출된 {this.state.name} 의 값도 마찬가지로 변경된다.
$("input").on("change", function(){
$(this).siblings("h1").html($(this).val())
});
jQuery에서였다면, 위 코드처럼 input요소에 직접 컨택하여,
해당 DOM요소를 기준으로 동작이 이루어지며,
직접 DOM요소들을 컨트롤 하게 된다.
상태가 바뀌면, 그 상태만 바꿀 것인지,
아니면 요소자체를 뒤흔들 것인지의 차이라고 할까.
물론 jQuery가 가지는 편리함이라는 강점은 어디 비할바가 못된다.
DOM요소를 직접 컨트롤하고, 해당 요소에 $(this)라는 선택자를 사용할 수 있다는 것만큼
압도적인 편리함을 주는 것은 없을 것이다.
다만, 관리자페이지나 ERP시스템 등을 비롯하여, 어플리케이션과 사용자간의 상호작용이 많은,
상태의 변화와 전달이 빈번한 시스템 상에서,
직접적으로 DOM요소를 관리하고 제어해야한다면 상상만으로 정말 끔찍하다.
React에서는 jQuery와 다르게 state를 이용해 변화가 필요한 부분에 유연하고 가볍게 변화를 적용할 수 있다.
props
state가 컴포넌트 내부적으로 가지고 있는 상태 라고 한다면,
props는 컴포넌트 외부로부터 받아 오는 상태값이다.
import React from "react";
import App from "./App";
export default class Temp extends React.Component{
render(){
return(
<App />
)
}
}
컴포넌트가 import되어 어딘가에 사용될 때, 위와 같은 식이 된다.
Temp라는 컴포넌트에서 import 해온 App을 반환한다.
여기서 Temp는 부모, App은 자식이다.
방금 props는 외부로부터 받아오는 상태값이라고 했는데,
다시 고쳐 말하자면, App이라는 컴포넌트가 부모(자신을 import한 다른 컴포넌트)로부터
전달받는 어떠한 상태값을 props라고 한다.
import React from "react";
export default class App extends React.Component{
constructor(props){
super(props);
this.state={
name:""
}
}
componentDidMount(){
this.setState({
name: this.props.name
})
}
handleChange = e => {
const name = e.target.value;
this.setState({
name
});
}
render(){
return(
<>
<h1>hi my Name is {this.state.name}</h1>
<input value={this.state.name} onChange={this.handleChange} />
</>
)
}
}
컴포넌트가 mount 되었을 때 사용하는,
jQuery에서의 $(document).ready(function(){}); 과 마찬가지로, 마운트 되었을 때 한번 실행하는 코드는,
componentDidMount에서 사용한다.
이번 예제에서, state의 name은 빈 문자열이다.
componentDidMount에서는 state의 name을 this.props.name이라는 값으로 변경해준다.
이는 곧, props로써 넘겨받는 name이라는 값을 this.state.name의 값으로 변경한다는 의미이다.
바꿔 말하자면, App 컴포넌트는 name이라는 이름의 props를 가질 수 있다는 것이다.
import React from "react";
import App from "./App";
export default class Temp extends React.Component{
render(){
return(
<App name="Albatro33" />
)
}
}
Temp 컴포넌트에서는 name 이라는 props에 "Albatro33"이라는 값을 App 컴포넌트에 전달했다.
Temp컴포넌트에 호출된 App컴포넌트는, Albatro33이라는 값을 받아, state의 name 값에 저장한다.
그러면 App컴포넌트가 출력되는 부분에는 "hi my Name is Albatro33"이라는 h1태그가 나타날 것이다.
import React from "react";
import App from "./App";
export default class Temp extends React.Component{
render(){
return(
<>
<App name="Albatro33" />
<App name="이순신" />
<App name="도롱뇽" />
</>
)
}
}
App 컴포넌트가 props를 넘겨받아 state값을 변경한다고 하면,
위처럼 App컴포넌트가 세개인 경우에는 어떨까?
App 컴포넌트의 구성은 h1, input 이다.
<h1>hi my Name is Albatro33</h1>
<input />
<h1>hi my Name is 이순신</h1>
<input />
<h1>hi my Name is 도롱뇽</h1>
<input />
각각 다른 name값을 전달받은 각각의 App 컴포넌트가 위와같이 화면에 출력되는 것이다.
또한 처음 접하는 경우 제일 헷갈릴 수 있는 부분이,
"name 은 정해진 것인가!?"이다.
처음 리액트를 보면서 가장 헷갈리고 이해도 안되고,
강좌를 아무리 봐도 이해할 수 없었던 부분이 바로 이것이다.
this.props.name;
this.props.text;
this.props.msg;
<App name="Albatro33" />
<App text="Albatro33" />
<App msg="Albatro33" />
이젠 헷갈리지 말자.
name이든, text든 msg든, 내가 받을 이름을 정하면 된다.
내가 만약 "꼬깔콘"이라는 이름을 받아올 prop를 만든다면,
this.props.snackName 이라고 지어서
<App snackName="꼬깔콘" /> 이라고 전달하면 된다.
결론
즉, React에서는 컴포넌트별로 내부적으로 상태를 설정하고 운용할 수 있게 해주는 state와,
자신을 호출하는 부모 컴포넌트로부터 어떤 값을 전달받아 운용할 수 있게 해주는 props를 통해,
복잡한 상호작용에 보다 유연하게 대처하게 된다.
새로 리액트를 접하는 사람들에게, 내 경험에 비추어
state와 props만 이해해도 반은 먹고 들어간다고 종종 말하곤 했다.
React.js의 가장 중요한 근간이 되는 요소이고,
실제로 state와 props를 어느정도 이해한 단계에서 복잡하지 않은 컴포넌트의 작성은 가능해졌기에,
더더욱 그렇게 믿고 있다.
복잡한 작업을 하면서도, 결국 state와 props는 항상 마주치기에
처음 접하는 경우라도, 혹은 접하긴 했으나 아직 이해가 잘 안된다면,
우선적으로 이해하기 위해 노력해야 하는 부분이라고 말하고 싶다.
p.s. jQuery에 너무 익숙하면....React초반에 너무 힘듭니다.......노오력이 필요합니다....
'Web開発 > React.js' 카테고리의 다른 글
React-native TextInput secure( input password ) (0) | 2020.03.03 |
---|---|
React-native 배경이미지 넣기 (0) | 2020.03.03 |
React.js Global State Management(전역 상태관리) 1. (0) | 2020.02.13 |
React Native 1 (0) | 2019.10.03 |