6. useState

dana·2021년 12월 10일
0

React.js

목록 보기
8/20
post-thumbnail

useState 인자값

const [count, setCount] = useState(0)

const click1 = () => {
  setCount(count+ 1);
  setCount(count+ 1);
  console.dir(count);
}

const click2 = () => {
  setCount(count=> count+ 1);
  setCount(count=> count+ 1);
  console.dir(count);
}

setCount에서 값을 변경해 저장하는 방법으로 다음과 같이 두가지 종류가 있다.

click1의 경우 count값을 불러와서 저장한다. 이 때 변경된 값이 바로 저장되는게 아니기 때문에,

setCount(count+ 1); -> (count = 1 : 저장 대기 중 | 현재 값 : count = 0)
setCount(count+ 1); -> (count = 1 : 저장 대기 중 | 현재 값 : count = 0)
console.dir(count); -> count = 0 이므로 0 출력

출력 후, 함수 실행이 끝난 뒤 count값 갱신

이렇게 출력되게 된다.

반대로 안에 화살표 함수를 넣어 count의 값을 변경해주게 되면

setCount(count=> count+ 1); -> (count = 1 : 저장 대기 중 | 현재 값 : count = 0)
setCount(count=> count+ 1); -> (count = 2 : 저장 대기 중 | 현재 값 : count = 1)
console.dir(count);

출력 후, 함수 실행이 끝난 뒤 count값 갱신

이렇게 두 변수 설정 방법에 차이가 나게 된다

그럼 왜 두 방법 모두 함수가 끝난 뒤 변수가 저장되는가 하면
useState가 변수를 변경하는 방식이 비동기로 일어나기 때문이다.
그래서 가급적이면 한 함수 안에서 변경과 값 불러오기가 동시에 사용되는 것을 권장하지 않는다.

여러 인자값을 한번에 다루기

여러개의 인자값을 다룰 때 모든 state를 만드는 것보다 객체를 이용해 묶어 사용하는 것이 권장된다.
예를 들어 여러 input의 값을 불러오는 경우,

import React, {useState} from "react";

function InputSample() {
    const [inputs, setInputs] = useState({
        realname: '',
        nickname: ''
    });

    // 비구조화 할당을 이용해 데이터 추출
    const { realname, nickname } = inputs;

    const onChange = (e) => {

        // 이벤트 타겟에서 name과 value 추출
        const {value, name} = e.target;
        setInputs({
            // 불변성을 지키지 위해 spread 문법 이용
            ...inputs,
            [name] : value
        })
    };

    const onReset = () => {
        setInputs({
            realname: '',
            nickname: '',
        })
    };

    return (
        <div>
            <input name = "realname" placeholder = "이름" onChange={onChange} value = {realname}/>
            <input name = "nickname" placeholder = "닉네임" onChange = {onChange} value = {nickname}/>
            <button onClick = {onReset}>초기화</button>
            <div>
                <b>: </b>
                {realname} ({nickname})
            </div>
        </div>
    );
}

export default InputSample;

...input을 해주지 않는 경우,

setInputs({
	// 불변성을 지키지 위해 spread 문법 이용
	//...inputs,
	[name] : value
})


오브젝트에 inputs값을 얕은 복사 하지 않으면, 기존 값이 저장되지 않는다.
...inputs 이렇게 입력하면
realname : value , nickname : value 값이 데이터로 들어와서

input = { 
    realname : value , 
    nickname : value ,
    [name] : value
}

이런식으로 작동하게 되는데

input = { 
    [name] : value
}

이렇게 기존 값이 새 오브젝트로 덮어지면서 사라져 버린다.

원래는 이런 값이 나와야한다.

profile
PRE-FE에서 PRO-FE로🚀🪐!

0개의 댓글