갬쿠
개미 개발
갬쿠
전체 방문자
오늘
어제
  • ALL (137)
    • React (20)
    • JS & CSS & HTML (29)
    • Algorithm (62)
    • 웹 보안 (11)
    • 달리는 까까: 쿠키런 팬게임 (10)
    • Python (0)
    • 기타 (5)
    • 비공개 플젝 (0)

블로그 메뉴

  • GitHub
  • 방명록
  • 관리자 메뉴

공지사항

인기 글

태그

  • 백준
  • 객체
  • EventListener
  • CSS
  • useEffect
  • 쿠키런 팬게임
  • 리액트
  • HTML
  • 크롬 공룡 게임
  • 달리는 까까
  • BEAKJOON
  • node.js
  • 크롬 공룡게임
  • useState
  • REACT
  • 쿠키런
  • SQL Injection
  • 모의 해킹
  • Object
  • Python
  • 쿠키런 모작
  • 게임 개발
  • 게임
  • Programmers
  • Best of the Best
  • transform
  • Baekjoon
  • js
  • JavaScript
  • useReducer

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
갬쿠

개미 개발

React

State 작동 방식

2023. 8. 8. 01:40

그동안 state의 작동 방식에 대해 제대로 이해를 못한 채로 코드를 짜서 기능이 내 의도와 다르게 돌아간 적이 많았다. setState를 사용하면 state 값이 바로 바뀌고 해당 state를 그려주는 부분이 다시 그려진다고만 알고 있었는데, 자세히 들여다보니 그게 아니었다.

 

const [ count, setCount ] = useState(0)

function onClickCountUp() {
	setCount(5)
}

return (
	<div>
		<div>{count}</div>
		<button onClick={onClickCountUp}>카운트</button>
	</div>
)

위 코드의 동작 방식은 다음과 같다.

  1. 버튼을 클릭하면 setCount() 함수가 실행됨 → setCount: count 값 비교 (같으면 무시)
  2. 다르면
    1. count 값을 5로 바꾸기
    2. 화면 다시 그리기(리렌더링) → 위에서부터 하나씩 다시 실행
      • 변수도 function도 새롭게 만들어짐
      • return 안에 있는 부분도 다시 그림 → 이번에는 count가 5니까 5가 출력됨
      • 실제로는 전체 화면이 다시 그려지고 있는 것

 

만약

const [ count, setCount ] = useState(0)

function onClickCountUp() {
	setCount(7)
	setCount(2)
	setCount(5)
	setCount(9)
	setCount(1)
}

return (
	<div>
		<div>{count}</div>
		<button onClick={onClickCountUp}>카운트</button>
	</div>
)

위와 같은 코드를 실행하면 count가 7→2→5→9→1로 바뀌면서 화면이 다섯 번 그려질까? 결국엔 1 하나만 보이는데 비효율적이다.
따라서 무의미한 리렌더링을 방지하기 위해, 내부적으로 setCount(7)을 만났을 때 임시 저장 공간에 7을 넣어 놓고 바로 state를 바꾸지는 않는다. 임시 공간에 (count: 7) → (count: 2) → (count: 5) → (count: 9) → (count: 1) 을 넣어 놓고, 함수가 끝났을 때 count를 1로 바꾸고 화면을 다시 그리게 된다.

즉 화면은 한 번만 다시 그린다!

 

따라서

const [ isActive, setIsActive ] = useState(false)

const [ writer, setWriter ] = useState()
const [ title, setTitle ] = useState()
const [ contents, setContents ] = useState()

const onChangeWriter = (event) => {
	setWriter(event.target.value)
	
	if(writer && title && contents) {
		setIsActive(true)
	}
}
const onChangeTitle = (event) => {
	setTitle(event.target.value)
	
	if(writer && title && contents) {
		setIsActive(true)
	}
}
const onChangeContents = (event) => {
	setContents(event.target.value)
	
	if(writer && title && contents) {
		setIsActive(true)
	}
}

이렇게 writer, title, contents 모두 내용이 작성되었을 때 isActive로 버튼을 활성화 하려는 코드를 작성했을 때의 문제점은 내용을 한 글자씩만 입력하면 버튼이 활성화되지 않는다는 것이다. 함수 안의 if문에서는 아직 state가 변경되지 않은 상태이기 때문! 함수가 한 번 끝나고 나면 업데이트 되기 때문에 두 글자 부터는 잘 동작한다.
이 코드에서의 해결법은 event.target.value를 바로 if문에서 비교하도록 하는 것이다(state는 한 박자씩 느리기 때문에).

728x90

'React' 카테고리의 다른 글

useReducer  (0) 2023.09.12
useEffect로 state 변경 바로 감지하기  (4) 2023.08.08
styled component에 css animation 적용 (재생되는 텍스트 만들기)  (0) 2023.07.18
Error Boundary  (0) 2023.07.15
Styled component로 React Component 디자인  (0) 2023.07.13
    'React' 카테고리의 다른 글
    • useReducer
    • useEffect로 state 변경 바로 감지하기
    • styled component에 css animation 적용 (재생되는 텍스트 만들기)
    • Error Boundary
    갬쿠
    갬쿠
    보안&소프트웨어 전공 프론트엔드 개발자

    티스토리툴바