프론트 108 - set state

규링규링규리링·2024년 9월 13일

프론트 공부하기

목록 보기
108/135

set state

변수에 있는 값을 화면에 내보내 주는 기능

  1. 활성화 버튼을 만들어보기
  2. setState의 원리

활성화 버튼

Input 상자의 값이 있을때만 클릭이 가능해지는 활성화 버튼

만들어보기

<BlueButton onClick={props.aaa} isActive={true} >

버튼에 isActive 를 만들어 주게되면 해당 버튼 BluButton에 props로 값을 보낼 수 있게됨.

export const BlueButton = styled.button`
    background-color: ${(props)=> props.isActive ? "yellow" : ""}; 
`

BlueButton 자체에는 props를 받아올 수없으니
값에서 함수를 만들어서 바로 대입이 가능
위 코드의 경우는 isActive의 값이 true면 yellow , false면 기본값인 회색이 출력된다.

이제 해당 조건을 input 세칸의 값의 유무에따라 true, false를 조절하면 된다.

setState

값의 입력 유무를 확인하기 위해서 setState를 사용

const [isActive, setIsActive] = useState(false)

isActive라는 State를 만들고 기본값은 false로 설정

const onChangeWriter = (event) => {
  setWriter(event.target.value)
  if(writer && title && contents){
    setIsActive(true)
  }else{
    setIsActive(false)
  }
}

const onChangeTitle = (event) => {
  setTitle(event.target.value)
  if(writer && title && contents){
    setIsActive(true)
  }else{
    setIsActive(false)
  }
}

const onChangeContents = (event) => {
  setContents(event.target.value)
  if(writer && title && contents){
    setIsActive(true)
  }else{
    setIsActive(false)
  }
}

각 인풋칸에 값을 입력할때마다 인풋값의 값이 있는지 확인하여 3칸 모두 값이 있으면 True를 반환하는 if문을 작성
하지만

조건이 딱 맞았을때는 동작하지 않고 한번 더 동작시켜야지 적용이됨
이건 setState의 동작원리에 대해 알아야함.

setState 동작 원리

이전에 만들었던 카운터 페이지를 보자

import { useState } from "react"
// useState를 기능을 쓰기 위해서 react 에서 가져오는것

export default function CounterLetDocumentPage(){
    const[ count, setCount ] = useState(0)

    function onClickCountUp () {
        setCount(count + 1)
    }

    function onClickCountDown () {
        setCount(count - 1)
     }

    return(
        <div>
            <div>{count}</div>    
            <button onClick={onClickCountUp}>카운트 올리기</button>
            <button onClick={onClickCountDown}>카운트 내리기</button>
        </div>
    )
}

보이는대로 카운트 올리기를 누르면 숫자가 올라가고
카운트 내리기를 누르면 숫자가 내려가는 간단한 코드이다.
각 버튼을 누르면 -> fuction을 통해 숫자가 +- 되고 -> setCount를 통해 저장된 count값이 <div>{count}</div> 부분을 통해 출력된다고 볼 수 있다.

const[ count, setCount ] = useState(0)와 <div>{count}</div>가 연결되어 있다고 생각할 수 있다.

하지만 실제로는 순서가 조금 다르다.
정확하게는 setCount 함수 내부의 동작 순서가 조금 다르다.
1. 들어온 값과 현재 값을 비교함
2. 같으면 굳이 실행할 필요가 없기에 무시
3. 다르면 기존값을 지우고 신규 값으로 바꿔줌
4. 화면을 다시 그린다. < 중요 >

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

만약 함수 안에 setCount가 5개가 있다고 생각해보면
setCount가 하나씩 돌아갈 때마다 화면을 다시그릴까?
아니면 모든 setCount를 끝내고 화면을 다시 그리게 될까?

정답은 후자이다.
setState는 무의미한 리랜더링을 방지하기 위해서
내부에 임시 저장공간을 만들어서 setCount의 값들을 집어넣고 모든 setCount가 끝난 뒤 최종 값을 count에 저장하고 리랜더링을 한번만 하게 된다.

그럼 다시 돌아와서

const onChangeWriter = (event) => {
  setWriter(event.target.value)
  if(writer && title && contents){
    setIsActive(true)
  }else{
    setIsActive(false)
  }
}

해당 코드를 다시한번 봐보자.

작성자 부분에 한글자를 입력하면
기존 writer의 값은 빈값이고
event.target.value 은 a 가 될것이다.
a 값이 setWriter로 저장이됨. ( 아직 writer 까지 바뀐게 아닌 임시 저장공간에 들어가 있음)
이후 if문을 확인 이때는 writer의 값이 빈값이기에 false를 반환하게 됨.
if문 까지 종료되고 나서야 writer에 a 라는 값이 저장되게됨.

해결 방법

if문 자체를 event.target.value의 값을 확인하도록 수정하면 된다

const onChangeWriter = (event) => {
  setWriter(event.target.value)
  if(event.target.value && title && contents){
    setIsActive(true)
  }else{
    setIsActive(false)
  }
}

const onChangeTitle = (event) => {
  setTitle(event.target.value)
  if(writer && event.target.value && contents){
    setIsActive(true)
  }else{
    setIsActive(false)
  }
}

const onChangeContents = (event) => {
  setContents(event.target.value)
  if(writer && title && event.target.value){
    setIsActive(true)
  }else{
    setIsActive(false)
  }
}

정상적으로 즉각 적용되는걸 볼 수 있다.

0개의 댓글