jineecode
state 본문
src/Counter.js
import React, { Component } from "react";
class Counter extends Component {
constructor(props) {
super(props);
this.state = {
//state의 초깃값 설정하기
number: 0;
}
}
render() {
const { number } = this.state;
return (
<div>
<h1>{number}</h1>
<button
onClick={() => {
this.setState({ number: number + 1 });
}}
>
+1
</button>
</div>
);
}
}
export default Counter;
class Counter extends Component {
constructor(props) {
super(props);
this.state = {
//state의 초깃값 설정하기
number: 0;
}
}
state를 작성할 때 constructor 메서드를 작성하여 설정한다.
클래스형 컴포넌트에서 constructor를 작성할 때는 super(props)를 호출해야 한다.
이 함수가 호출되면 현재 클래스형 컴포넌트가 상속받고 있는 리액트의 Component 클래스가 지닌 생성자 함수를 호출해준다.
그 다음에는 this.state 값에 초깃값을 설정한다.
컴포넌트의 state는 객체형식이어야 한다.
state는 이렇게도 쓸 수 있다.
state = {
number: 0,
fixedNumber: 0,
};
//
render() {
const { number } = this.state;
return (
<div>
<h1>{number}</h1>
<button
onClick={() => {
this.setState({ number: number + 1 });
}}
>
+1
</button>
</div>
);
}
}
render 함수에서 현재 state를 조회할 때 this.state를 조회한다.
이벤트로 설정할 함수를 넣어줄 때는 화살표 함수 문법을 사용해서 넣는다.
함수 내부에는 this.setState 함수를 사용하였는데, 이 함수가 state 값을 바꿀 수 있게 한다.
이 의미는 setState를 설정하지 않으면 그 state는 고정이 된다는 뜻이다.
import React, { Component } from "react";
class Counter extends Component {
constructor(props) {
super(props);
this.state = {
//state의 초깃값 설정하기
number: 0,
fixedNumber: 0,
};
}
render() {
const { number, fixedNumber } = this.state;
return (
<div>
<h1>{number}</h1>
<h2>바뀌지 않는 값 : {fixedNumber}</h2>
<button
onClick={() => {
this.setState({ number: number + 1 });
}}
>
+1
</button>
</div>
);
}
}
export default Counter;
setState를 두 번 쓰면 2 씩 올라갈까?
import React, { Component } from "react";
class Counter extends Component {
state = {
number: 0,
fixedNumber: 0,
};
render() {
const { number, fixedNumber } = this.state;
return (
<div>
<h1>{number}</h1>
<h2>바뀌지 않는 값 : {fixedNumber}</h2>
<button
onClick={() => {
this.setState({ number: number + 1 });
this.setState({ number: this.state.number + 1 });
}}
>
+1
</button>
</div>
);
}
}
export default Counter;
setState를 사용한다고 해서 state 값이 바로 바뀌지는 않기 때문에 1씩 더해진다.
setState를 사용할 때 객체 대신에 함수를 인자로 넣어주어서 바꿔주자.
this.setState((prevState, props)=> {
return {
}
})
prevState : 기존 상태
props: 현재 지니고 있는 props
import React, { Component } from "react";
class Counter extends Component {
state = {
number: 0,
fixedNumber: 0,
};
render() {
const { number, fixedNumber } = this.state;
return (
<div>
<h1>{number}</h1>
<h2>바뀌지 않는 값 : {fixedNumber}</h2>
<button
onClick={() => {
this.setState((prevState) => {
return {
number: prevState.number + 1,
};
});
// 위와 아래 코드는 같은 기능을 한다.
this.setState((prevState) => ({
number: prevState.number + 1,
}));
}}
>
+1
</button>
</div>
);
}
}
export default Counter;
화살표 함수에서 값을 바로 반환하고 싶다면 { } 을 생략하면 된다.
const sum = (a, b) => a + b;
return 이 { } 였다고 생각하면 쉽다.
setState의 두 번째 파라미터로는 콜백을 수행할 수 있다.
import React, { Component } from "react";
class Counter extends Component {
state = {
number: 0,
fixedNumber: 0,
};
render() {
const { number, fixedNumber } = this.state;
return (
<div>
<h1>{number}</h1>
<h2>바뀌지 않는 값 : {fixedNumber}</h2>
<button
onClick={() => {
this.setState(
{
number: number + 1,
},
() => {
console.log("방금 setState가 호출되었습니다.");
console.log(this.state);
}
);
}}
>
+1
</button>
</div>
);
}
}
export default Counter;
배열 비구조화 할당
객체 비구조화 할당처럼, 배열도 비구조화 할당을 할 수 있다.
ES6 :
destructuring
var [a, b] = [10, 100];
var a = 10
var b = 100
const array = [1, 2];
const one = array[0];
const two = array[1];
....위와 아래는 같다...
const array [1, 2];
const [one, tow] = array;
useState를 쓰게 되면 두 개의 자리가 있는 배열이 하나 생성된다.
[현재상태, 현재 상태를 바꾸어주는 함수]
ES6문법인 destructuring을 이용하여
좌우 배열을 맞추어 써주면 useState를 쓸 준비가 된다.
const [message, setMessage] = useState("");
함수형 컴포넌트에서 state를 사용하는 방법은, useState 함수를 사용하면 가능하다.
import React, { useState } from "react";
const Say = () => {
const [message, setMessage] = useState("");
const onClickEnter = () => setMessage("안녕하세요");
const onClickLeave = () => setMessage("안녕히 가세요");
return (
<div>
<button onClick={onClickEnter}>입장</button>
<button onClick={onClickLeave}>퇴장</button>
<h1>{message}</h1>
</div>
);
};
export default Say;
import React, { useState } from "react";
리액트에 있는 useState라는 내장함수를 쓰겠다는 뜻
state는 객체 형태로 넣어주어야 하지만 useState는 객체가 아니어도 상관없다.
함수를 호출하게 되면, 배열의 첫번째 원소는 현재 상태이고, 두 번째 원소는 상태를 바꾸어주는 함수이다.
이를 Setter 함수라고 한다.
useState의 두 번째 원소는, 기존의 state에 있는 값을 모두 갈아버린다. 등호를 쓰거나 특정 한 부분만 바꾸지 않고 모두 바꾸어준다.
useState는 여러 번 쓸 수 있다.
import React, { useState } from "react";
const Say = () => {
const [message, setMessage] = useState("");
const onClickEnter = () => setMessage("안녕하세요");
const onClickLeave = () => setMessage("안녕히 가세요");
const [color, setColor] = useState("black");
return (
<div>
<button onClick={onClickEnter}>입장</button>
<button onClick={onClickLeave}>퇴장</button>
<h1 style={{ color }}>{message}</h1>
<button style={{ color: "red" }} onClick={() => setColor("red")}>
빨간색
</button>
<button style={{ color: "green" }} onClick={() => setColor("green")}>
초록색
</button>
<button style={{ color: "blue" }} onClick={() => setColor("blue")}>
파란색
</button>
</div>
);
};
export default Say;
import React, { useState } from "react";
import logo from "./logo.svg";
import "./App.css";
function App() {
let posts = "데이터바인딩";
let [글제목, 글제목변경] = useState("오늘 한 일");
return (
<div className="App">
<div className="black-nav">
<div>개발 Blog</div>
</div>
<h4>{posts}</h4>
<div className="boardList">
<h3>{글제목}</h3>
<p>2월 17일 발행</p>
<hr />
</div>
<div className="boardList">
<h3>{posts}</h3>
<p>2월 17일 발행</p>
<hr />
</div>
<div className="boardList">
<h3>{posts}</h3>
<p>2월 17일 발행</p>
<hr />
</div>
</div>
);
}
export default App;
배열 형식으로 넣어도 아무런 문제가 없다.
import React, { useState } from "react";
import logo from "./logo.svg";
import "./App.css";
function App() {
let posts = "데이터바인딩";
let [글제목, 글제목변경] = useState(["오늘 한 일", "내일 할 일"]);
return (
<div className="App">
<div className="black-nav">
<div>개발 Blog</div>
</div>
<h4>{posts}</h4>
<div className="boardList">
<h3>{글제목[0]}</h3>
<p>2월 17일 발행</p>
<hr />
</div>
<div className="boardList">
<h3>{글제목[1]}</h3>
<p>2월 17일 발행</p>
<hr />
</div>
<div className="boardList">
<h3>{posts}</h3>
<p>2월 17일 발행</p>
<hr />
</div>
</div>
);
}
export default App;
그렇다면 왜 변수로 담아 사용하지 않고 state를 사용할까?
변수에 담아서 사용하면, 만약 글 제목이 바뀐다면 변수에 담았던 텍스트를 일일이 수정해야하며 새로고침을 해야 렌더링이 되는데 state를 사용하면 데이터를 담고있는 HTML이 자동으로 재렌더링된다.
즉, 자주 바뀌고 중요한 데이터는 state로 관리하는 게 좋다.
useState의 두 번째 파라미터를 이용하여 state를 변경할 때의 스킬
어떤 버튼이 있다.
let [title, changeTitle] = useState([
"오늘 한 일",
"내일 할 일",
"모레 할 일",
]);
function changeTitleFunction() {
changeTitle(["안녕", "내일 할 일", "모레 할 일"]);
}
<button onClick={changeTitleFunction}>바뀌는 제목</button>
첫 번째만 '안녕'으로 바꾸고 싶을 때:
버튼을 누르면
changeTitleFunction() 가 실행이 되고,
useState의 두 번째 파라미터(changeTitle)에 따라, 오늘 한 일이 안녕으로 바뀌게 된다.
하지만 배열에 담긴 데이터가 무수하다면?
이럴 때 특정 하나의 데이터만 바꿀 수 있는 방법이 있다.
리액트의 immutable data 에 따라 state를 직접 바꾸진 못하지만 state에 담긴 데이터를 '복사'하여 바꿀 수는 있다.
ES6 spread operator deep copy 문법:
[...] 혹은 {...}
값 공유가 일어나지 않고 완전히 별개의 새로운 복사본.
... : 중괄호, 대괄호 다 없애주세요
{...} : 중괄호, 대괄호 다 없앤 뒤 다시 중괄호를 만든 새로운 복사본
'JS > react' 카테고리의 다른 글
이벤트에 따른 class명 변경 (0) | 2021.04.29 |
---|---|
이벤트 핸들링 (0) | 2021.04.29 |
props (0) | 2021.04.27 |
궁금증 해소 (0) | 2021.04.27 |
componentDidMount() 응용. (0) | 2021.02.11 |