react

[React] useState로 여러 상태를 관리하는 법과 set함수에서 콜백함수 쓰는 이유

킹king 2023. 12. 13. 15:45
반응형

 

1. useState로 여러 상태를 관리하는 법

고객 정보를 받는 input이 2개가 있다고 한다면 보통 이렇게 각각 state두고 관리할 것임.

const [age, setAge] = useState(0);
const [username, setUsername] = useState('');

그런데 이런 각각의 코드를

const [userData, setUserData] = useState({
  age: 0,
  username: ''
});

이렇게 한꺼번에 받을 수 있음. 어차피 같은 역할을 하는 친구들이면 저렇게 받는게 훨씬 깔끔하고 편할 수 있음. 

 

 

2. set함수에 콜백함수 쓰는 이유

만약 input창에 onchange 이벤트를 걸어서 쓸때마다 set함수로 해당 변수를 바꿔준다면 이렇게 쓰면 된다.

// jsx
<input type="text" change={handler} />

const handler = (event) => {
  setUserData({
    username: event.target.value,
  });
};

일단 저 input이 username용이라고 쳤을때 예시임. 근데 저렇게쓰면 안돼고 처음에 같이 썼던 다른 키들(age 등)도 데려가줘야함.

const handler = (event) => {
  setUserData({
    ...userData,
    username: event.target.value,
  });
};

이렇게 한다면 기존 age와 username을 가져온 뒤 다시 username을 새값으로 오버라이딩하기때문에 문제가 없음.

 

 

근데 여기서도 한가지 알아야하는게 보통은 문제가 없겠지만 간혹 잘못된 값으로 처리될 수 있음. 리엑트는 가상돔을 활용해 기존 dom과 바뀐부분이 있다면 그것만 바꿔주는 형태를 지니고 있음. 근데 이것도 매번 바뀌면 매번 비교해야하니까 복잡해짐. 그래서 이를 조금이나마 방지하기위해 랜더링 되는 요소를 모아서 16ms에 한번씩 일괄적으로 변경함(그래서 비동기적이라고 하는것임).

 

즉 바로 위에서 쓴 ...userData가 무의식적으로 바로 이전값이라 생각하고 우리가 쓴거지만 사실은 아닐 수도 있다는 것임. 그렇다면 해결방법은? 바로 함수형으로 쓰는 것임.

 

const handler = (event) => {
  setUserData((prevData) => {
    ...prevData,
    username: event.target.value,
  });
};

이렇게 set함수 내에 다시 함수를 쓰면 자동으로 인자로 이전값(최신값)을 받을 수 있음. 그걸 활용하여 써주면 아주아주굿굿 문제가 안생김.