keyword
state, useState(), setState(), re-rendering
요약
useState
, setState
사용 장점
데이터(값)를 업데이트시키고 메인 컴포넌트를 리렌더링함
즉, state가 바뀌면 리렌더링을 자동으로 발생시킴.
state 상태변경값 변수선언 -> Event Listen -> Event Update -> UI display
state
state
기본적으로 데이터가 저장되는 곳
state, event listening, update, re-rendering
어떻게 하면 React.js 어플리케이션에서 바뀌는 데이터값을 담아줄 수 있을까?
(1) 가변하는 데이터 저장 변수 + (2) 이벤트 리스닝 (3) 이벤트 업데이트 + (3) 새로고침(리렌더링) 방법
- (bad way) 일반 변수선언 + 실행 함수 + 리렌더링 함수 = 수작업 업데이트
변수를 JSX함수에 전달하는 방법? {변수명}
예제
카운트업 함수 만들기
<!DOCTYPE html>
<html lang="en">
<head> </head>
<body>
<div id="root"></div>
</body>
<!-- react.js-->
<script src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
const root = document.getElementById("root");
let counter = 0;
function countUp() {
counter = counter + 1;
render();
}
function render() {
ReactDOM.render(<Container />, root);
}
function Container() {
return (
<div>
<h3>Total Click: {counter}</h3>
<button onClick={countUp}>Click me</button>
</div>
);
}
//ReactDOM.render(<Container />, root);
render();
</script>
</html>
단점
: 데이터가 바뀔 때마다, 계속해서 리렌더링 함수 render();
를 호출 해줘야함.
이유
: 위 컴포넌트는 단 한번만 렌더링하고 끝이고, UI를 새로고침해주는 코드가 없기 때문에, 새로 리렌더링 함수를 다른 함수 실행시 매번 같이 실행해줘야 함.
리액트
VS바닐라자바스크립트
업데이트 차이
자바스크립트
는 카운터가 업데이트 될 때, 해당 태그 전체가 업데이트 됨.
<span>
태그 전체<span>Total Clicks: 1</span>
이 업데이트 됨리액트
는 UI에서 바뀐 부분만 업데이트 함.
{counter}
부분만 업데이트 함. <h3>
"Total Click:"
등 다른 태그들을 재생성할 필요도 없음. 리액트.js
업데이트 방식
리액트 장점
- (best way) useState 변수 선언 + 실행함수 = 자동 업데이트
기존 방법
let counter = 0; 변수에 담기
새로운 방법
let counter = useState(초기값);
👉 콘솔창에 Array배열을 받게됨.
👉 [undefined, f함수] 배열은
[(현재)데이터, 데이터를 바꿀때 사용하는 함수]를 의미.
(=> 위 두 요소들이, 우리가 이전 예제의 counte변수와 countUp()함수의 역할을 대신해주고 있음.)
useState() 방법 예제
function App() {
const data = React.useState();
console.log(data);
return (
<div>
<h3>Total Click: {counter}</h3>
<button>Click me</button>
</div>
);
}
ReactDOM.render(<App />, root);
React.useState() 함수는 초기값을 설정 가능.
const data = React.useState(0);
만약에 데이터값을 사용하고 싶다면? data[0], data[1] 이렇게 접근 가능.
const data = React.useState(999);
const counter = data[0];
const modifier = data[1];
❗더 좋은 방법
구조분해할당으로 처리
let counter = React.useState(초기값);
=> let [currentValue, modifier] = React.useSatet(초기값)
<script type="text/babel">
const root = document.getElementById("root");
function App() {
const [counter, modifier] = React.useState(0);
return (
<div>
<h3>Total Click: {counter}</h3>
<button>Click me</button>
</div>
);
}
ReactDOM.render(<App />, root);
</script>
const -> let
으로 변경let [counter, modifier] = React.useState(0);
const onClick = () => {
counter = counter + 1;
console.log(counter);
};
<button onClick={onClick}>Click me</button>
const [counter, setCounter] = React.useState(0);
const onClick = () => {
setCounter(counter + 1);
};
최종 코드
<!DOCTYPE html>
<html>
<body>
<div id="root"></div>
<script src="https://unpkg.com/react@17.0.2/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/@babel/standalone@7.17.6/babel.min.js"></script>
<script type="text/babel">
const root = document.getElementById("root");
function App() {
const [counter, setCounter] = React.useState(0);
const onClick = () => {
setCounter(counter + 1);
};
return (
<div>
<h3>Total clicks: {counter}</h3>
<button onClick={onClick}>Click me</button>
</div>
);
}
ReactDOM.render(<App />, root);
</script>
</body>
</html>
❗setState() 사용법
setState() 함수를 셋팅하는 2가지 방법
1) 직접할당: setState(현재값+1)
setState(state+1)
const [counter, setCounter] = React.useState();
const onClick = () => {
setCounter(counter+1);
};
2) 함수할당: setState((현재값) => {리턴값&규칙}) 함수
setState((state) => (state+1))
const [counter, setCounter] = React.useState(0);
const onClick = () => {
setCounter((current) => current + 1);
};
결론
: 2번 함수할당 방식이 현재값 업데이트에는 더 좋음
이유
:
전체코드
<!DOCTYPE html>
<html>
<body>
<div id="root"></div>
<script src="https://unpkg.com/react@17.0.2/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/@babel/standalone@7.17.6/babel.min.js"></script>
<script type="text/babel">
const root = document.getElementById("root");
function App() {
const [counter, setCounter] = React.useState(0);
const onClick = () => {
setCounter((current) => current + 1);
};
return (
<div>
<h3>Total clicks: {counter}</h3>
<button onClick={onClick}>Click me</button>
</div>
);
}
ReactDOM.render(<App />, root);
</script>
</body>
</html>
보충 설명 (setState())
1.직접할당 2.함수할당 결과값 차이
예제
아래와 같이 코드를 넣고 실행해보면,
function onClick() {
setCounter(counter + 1);
setCounter(counter + 1);
setCounter(counter + 1);
setCounter(counter + 1);
setCounter(counter + 1);
}
2번 함수할당: 함수로 여러번 호출한 결과값 5,10,15,20
function onClick() {
setCounter(current => current+ 1);
setCounter(current => current+ 1);
setCounter(current => current+ 1);
setCounter(current => current+ 1);
setCounter(current => current+ 1);
}
결과
<참고>
https://nomadcoders.co/react-for-beginners
https://ko.reactjs.org/tutorial/tutorial.html
<더 읽어보기>
SyntheticEvent, Event Pooling, event.persist():
https://ko.reactjs.org/docs/events.html
https://ko.reactjs.org/docs/handling-events.html
https://medium.com/react-native-seoul/react-%EB%A6%AC%EC%95%A1%ED%8A%B8%EB%A5%BC-%EC%B2%98%EC%9D%8C%EB%B6%80%ED%84%B0-%EB%B0%B0%EC%9B%8C%EB%B3%B4%EC%9E%90-06-%ED%95%A9%EC%84%B1-%EC%9D%B4%EB%B2%A4%ED%8A%B8%EC%99%80-event-pooling-6b4a0801c9b9
https://abangpa1ace.tistory.com/129
https://frontcode.tistory.com/60