[React] ReactJS로 영화 웹 서비스 만들기 (4)
Lpla
·2021. 2. 11. 18:52
반응형
#3 STATE
클래스형 컴포넌트(Class Component)
- state는 객체(Object)이고 동적 데이터를 작업할 때 사용한다.
- 이전에 사용한 함수형 컴포넌트(function component)는 값을 return 한다.
import React from 'react';
function App(props) {
return <h1>이것은 function 컴포넌트이다.</h1>
}
export default App;
- 클래스형 컴포넌트는 return 대신 render 메서드를 사용한다.
import React from 'react';
class App extends React.Component {
render() {
return <h1>이것은 Class 컴포넌트이다.</h1>
}
}
export default App;
- 간단한 함수형 컴포넌트 대신 클래스형 컴포넌트를 사용하는 경우는 언제일까?
- 동적 데이터 예제를 만들어보자.
import React from "react";
class App extends React.Component {
state = {
count: 0,
};
add = () => {
console.log('더하기');
};
minus () => {
console.log('빼기');
};
render() {
return (
<div>
<h1> 현재 값: {this.state.count} </h1>
<button>더하기</button>
<button>빼기</button>
</div>
);
}
}
export default App;
- state는 0이고 {this.state.count} 로 0을 출력했다.
- 이제 더하기를 누르면 add가 동작하고, 빼기를 누르면 minus가 동작하도록 연결해야 한다.
자바스크립트
<button onclick=add();>더하기</button>
<button onclick=minus();>빼기</button>
리액트
<button onClick={this.add}>더하기</button>
<button onClick={this.minus}>빼기</button>
- 자바스크립트는 onclick이나 eventListenr로 연결할 수 있고 리액트도 onClick 을 사용한다.
- 단순하게 1씩 더하거나 뺀다면 자바스크립트에서 흔히 사용하는 방법대로 하면 되지 않을까 싶지만 안 된다.
add = () => {
this.state.count++;
console.log('더하기');
};
minus = () => {
this.state.count--;
console.log('빼기');
};
- state를 직접 변경하지 마라는 경고와 함께 실제로도 작동하지 않는다.
- 이렇게 코드를 만들면 리액트는 render 함수를 호출하지 않는다.
- state를 변경하는 방법은 setState()로 state를 업데이트하는 것이다.
add = () => {
console.log(this);
this.setState({ count: this.state.count+1 });
};
minus = () => {
console.log(this);
this.setState({ count: this.state.count-1 });
};
- state를 수정하는데 this.state를 사용하는게 싫다면 다른 화살표함수로 한 번 더 묶어주면 된다.
add = () => {
console.log(this);
this.setState(current => ({count: current.count+1}));
};
Life Cycle
- 위 예시에서 add 함수와 minus 함수는 우리가 직접 만든 것이고 render 함수는 원래 리액트 클래스 컴포넌트가 가지고 있던 것이다.
- 리액트는 생명주기(Life Cycle)를 가지는데 컴포넌트가 생성되거나 없앨 때 호출되는 메서드를 말한다.
- render 함수도 그 중에 하나이고 자세한 내용은 이 사이트에서 확인할 수 있다.
- 'Mounting' 이란 컴포넌트가 처음 실행되는 것을 말한다.
- 'Updating' 은 알테니 넘어가고 'Unmounting'은 컴포넌트가 제거되는 것을 말한다.
Mounting
- constructor()는 자바스크립트에서 클래스를 만들 때 호출된다. 컴포넌트가 마운트될 때, render() 보다 먼저 호출된다. 반드시 super(props) 를 먼저 호출해야 한다.
- render()는 클래스 컴포넌트에서 반드시 구현해야하는 유일한 메서드다. 함수 내부는 순수(호출될 때마다 동일한 결과를 반환) 해야 하고 브라우저와 직접적으로 상호작용을 하지 않는다.
- componentDidMount()는 마운트 된 직후 호출된다.
Updating
- componentDidUpdate()는 업데이트 직후 호출된다. setState()를 호출하면 컴포넌트가 호출되고, render()가 호출되고, componentDidUpdate()가 호출된다.
Unmounting
- componentWillUnmount()는 컴포넌트가 제거되기 직전에 호출된다. 이후 다시 마운트되지 않는다.
리액트 공식사이트에 잘 설명된 이미지가 있어서 함께 첨부한다.
사전 준비
- 영화 웹 서비스를 만들기 전 사전준비 작업을 하자.
import React from "react";
class App extends React.Component {
state = {
isLoading: true
};
render() {
return <div>{this.state.isLoading ? "로딩중..." : "준비완료"}</div>
}
}
export default App;
- 삼항조건연산자로 조건문을 만들었다.
- JSX에서는 자바스크립트에서 사용하는 if문을 사용할 수 없다.
- 따라서 간단한 식은 삼항조건연산자로 하고 복잡한 식은 즉시발동함수로 해야 한다.
render() {
return (
<div> {
(()=> {
if(this.state.isLoading) {
return ("준비완료")
} else {
return ("로딩중")
}
})
}</div>
)
}
- 여기선 삼항연산자로 한다고 가정하고, this.state는 다시 짧게 바꿀 수 있다.
render() {
const { isLoading } = this.state;
return <div>{isLoading ? "로딩중..." : "준비완료"}</div>;
}
- 만약 처음 마운트될 때 '로딩중...' 이었다가 5초 뒤에 '준비완료' 로 바꾸고 싶다면 어떻게 해야 할까?
- 먼저 render()로 '로딩중...'을 띄우고 componentDidMount()로 '준비완료'로 바꿔야 한다.
import React from "react";
class App extends React.Component {
state = {
isLoading: true,
};
componentDidMount() {
setTimeout(() => {
this.setState({ isLoading: false })
}, 5000);
}
render() {
const { isLoading } = this.state;
return <div>{isLoading ? "로딩중..." : "준비완료"}</div>;
}
}
export default App;
- componentDidMount에 자바스크립트의 setTimeout을 사용하여 5초 뒤에 isLoading 값을 true로 바꾼다.
- 새로고침하면 정상적으로 작동하는 것을 확인할 수 있다.
반응형