state
동적데이터를 다루는데 사용된다. 변경될 가능성이 있는 데이터를 말한다.
클래스형 컴포넌트에서 사용되는 개념이다.
클래스형 컴포넌트
App 클래스가 React Component 클래스를 상속받도록 extends React.Component를 붙인다. 클래스형 컴포넌트의 뼈대이다.
class App extends React.Component{
}
App 클래스는 React.Component 클래스를 상속받았다. (상속을 통해 React.Component의 기능을 App에서도 동작할 수 있다)
클래스형 컴포넌트가 되려면 App 클래스가 리액트가 제공하는 Component 클래스를 반드시 상속받아야 한다는 것이다.
App은 현재 함수가 아니고 컴포넌트 이기 때문에 return을 사용해 반환을 할 수 없다.
컴포넌트의 반환을 시키고 싶으면 render() 함수를 사용해 return을 한다.
(React에서는 클래스형 컴포넌트의 render함수는 자동으로 실행시켜준다.)
class App extends React.Component{
render() {
return <h1> This is class Component</h1>;
}
}
export default App;
다시 State
그럼 이러한 클래스형 컴포넌트를 통해 State를 사용해보자.
State는 다음과 같이 선언하는데 객체 형태의 데이터 처럼 표현한다. state는 반드시 클래스형 컴포넌트 안에서 소문자로 state라고 적는다.
class App extends React.Component{
state = {};
render() {
return <h1> This is class Component</h1>;
}
}
export default App;
이제 state에서 count라는 키를 통해 0에서 부터 하나씩 올라가도록 구현해볼 것이다. 다음과 같이 state 내에서 count를 0이라고 선언한다. 그리고 render()함수에서 {this.state.count}를 출력한다.
class App extends React.Component{
state = {
count: 0;
};
render() {
return <h1> This number is : {this.state.count} </h1>;
}
}
export default App;
state는 동적으로 데이터를 저장하기 때문에 count를 지속적으로 바꾸는 기능을 추가해보자. 다음과 같이 버튼으로 가감 버튼을 만든다.
class App extends React.Component{
state = {
count: 0;
};
render() {
return (
<div>
<h1> This number is : {this.state.count} </h1>;
<button> Add </button>
<button> Minus </button>
</div>
);
}
}
export default App;
이제 Add, Minus 기능을 위해서 함수를 정의하고 버튼에 이식한다.
button 엘리먼트에는 onClick 속성을 통해서 해당 값이 적용되도록 한다.
class App extends React.Component{
state = {
count: 0;
};
add = () => {
console.log('add')
}
minus = () => {
console.log('minus')
}
render() {
return (
<div>
<h1> This number is : {this.state.count} </h1>;
<button onClick={this.add}> Add </button>
<button onClick={this.minus}> Minus </button>
</div>
);
}
}
export default App;
참고로 state는 직접 변경할 수 없다. 변경시에는 Do not mutate state directly라는 에러를 만나게 될 것이다.
원래 React가 변경되면 render()함수를 실행해서 변경된 state를 화면에 출력하는데 state를 직접 변경할 경우 render()함수가 다시 실행되지 않는다. 이는 React가 직접 state 변경을 막아뒀기 때문이다.
만약 수정을 하고 싶으면 간접적인 방법으로 수정해야하는데 그게 setState()이다.
setState()
setState에 인자로 count 값의 증감을 표현했다. React에서는 setState함수의 호출을 감시하다가 함수가 동작하면 state 값을 갱신하고 render()함수를 실행시켜 화면을 업데이트 한다.
class App extends React.Component{
state = {
count: 0;
};
add = () => {
this.setState({ count: 1 });
}
minus = () => {
this.setState({ count: -1 });
}
render() {
return (
<div>
<h1> This number is : {this.state.count} </h1>;
<button onClick={this.add}> Add </button>
<button onClick={this.minus}> Minus </button>
</div>
);
}
}
export default App;
다만 state에 직접 계산을 하는 방식은 성능에 문제가 생길 수 있기 때문에 setState()함수의 인자로 함수를 전달하면 성능 문제 없이 state를 업데이트 할 수 있다.
그래서 current 인자를 받아 객체 ({ count: current.count + 1})를 반환하는 함수를 만들어 setState()에 전달해보자.
import React from 'react';
class App extends React.Component{
state = {
count: 0
}
add = () => {
this.setState(current => ({
count: current.count + 1,
}));
}
minus = () => {
this.setState(current => ({
count: current.count - 1,
}));
}
해당 방식에서는 current에 현재 state가 넘어와 state의 count에 1을 더하거나 빼는 방식이다.
참고로 setState()는 변경된 state 데이터만 변경한다. 변경되지 않는 것은 변경하지 않고 유지된다.
클래스형 컴포넌트
componentDidMount()
컴포넌트가 처음 화면에 그려지면 실행되는 함수이다.
constructor() - render() - componentDidMount() 순으로 실행된다.
componentDidUpdate()
해당 함수는 화면이 업데이트 되면 자동으로 실행된다.
setState() - render() - componentDidUpdate() 순으로 진행된다.
componentWillUnmount()
컴포넌트가 화면에서 죽거나 없어지게 되면 실행된다.
로딩바를 위한 isLodingState
bool 값으로 로딩중일때 false이고 컴포넌트가 마운트되면 true가 된다.
import React from 'react';
import Axios from 'axios';
class App extends React.Component {
state = {
isLoding: true,
movies: [],
};
componentDidMount() {
setTimeout(() => {
this.setState({ isLoding: false });
// this.setState( {isLoading:false}, movies: [영화데이터]} ) 도 된다.
}, 6000);
}
render() {
const { isLoding } = this.state;
return (<div>{isLoding ? '로딩중...' : '로딩 완료'}</div>)
}
}
export default App;
axios 사용하기
npm install axios
영화 api 사용 사이트 : https://yts.mx/api
class App extends React.Component {
state = {
isLoding: true,
movies: [],
};
getMovies = async () => {
const movies = await axios.get("https://yts.mx/api/v2/list_movies.json");
}
componentDidMount() {
this.getMovies();
}
render() {
const { isLoding } = this.state;
return (<div>{isLoding ? '로딩중...' : '로딩 완료'}</div>)
}
}
export default App;
async(비동기)는 시간을 기다리는 말이고, await(함수 내부 실행완료를 기다렸다가 끝나면 계속 진행)는 실제로 실행되서 기다리게 될 대상이다.
react-router-dom
내비게이션 기능
npm install react-router-dom
router 기능의 2가지 유의점
router가 찾을 때 상단부터 찾기때문에 여러개가 그려지는 문제가 있다.
a href는 모든 페이지를 다시 그리기 때문에 페이지를 지속적으로 새로고침하는 이슈가 있다.
import {Link} from "react-router-dom";
<a href="/about"> About</a>
# 변경
<Link to="/about"> About</Link>
route에 있는 history 키
push, go, goBack, goForward 등이 있다. URL을 변경해주는 함수이다.
push : 지정 url로 전송함.