-
setState()심화React 2022. 1. 17. 18:12
리엑트 렌더링에서 함수컴포넌트 = just regular function이다. 차이가 있다면 JSX를 리턴하고 있다는 것.
함수는 누군가 불러와야 사용이 된다. 함수형컴포넌트를 보면 분명히 다른곳에서 불러오는 JSX가 있을 것이다.리엑트가 여기서 JSX를 통해 함수형컴포넌트 들을 하나씩 빠짐없이 호출하고 이것을 DOM명령어로 변환하여 화면에 출력한다.
중요한점은 리엑트는 이 행동을 절대로 다시 반복하지 않는다. 즉 초기에 렌더링 되었을때만 모든 함수를 호출한다.
이로 인해 벌어지는일이 컴포넌트 내의 변수가 바뀌더라도 컴포넌트 함수는 다시 재실행 되지 않기 때문에 화면에서 그 변수값을 렌더링하고 있는 부분이 있다면 화면상에 변화가 나타나지 않는다.
화면을 변화(재렌더링) 하게끔 함수를 다시 호출하기 위해서는 state를 바꿔줘야 한다.
setState(value)와 같은 형태로 값을 받는데 여기서 새로운 value만 받는것이 아니라, state update함수라고 부르는 컴포넌트 함수도 state내부적으로 받으면서 useState로 초기화된 상태의 컴포넌트 함수가 다시 실행되는 것이다.
즉 컴포넌트 함수를 다시 불러옴=>화면의 변화(재랜더링)을 가능하게 하는 것이다.
useState는 상태를 등록함/ 상태로써의 값 호출된 컴포넌트를 위한 값/ 이는 컴포넌트 인스턴스를 위해 등록함
컴포넌트도 인스턴스가 있음(인스턴스란 JSX에서 <ExpenseItem>과 같이 다르 컴포넌트에서 호출할 때)
각 인스턴스는 각자 다른 state를 가지고 있음
State가 변함
react가 상태를 초기화 해주지 않음. 대신 과거에 초기화 되었을 때를 추적해서 상태업데이트
에 기반을 둔 최신 상태를 가지고 갈것임. 그리고 그 상태를 대신 제공해줌멀티 state를 하나의 객체로 표현할 때 보통 다음과 같은 방식을 사용하게 된다.
즉 위와 같이 useState에 객체를 넣고
이 객체 안의 key값을 바꾸어주는데
setLoginInfo({userEmail:event.target.value})
이런식으로 하게되면 나머지 key 값인 userPassword는 버리게 된다. 왜냐하면 여기서 state가 업데이트 될 때 리엑트가 예전 state와 병합하지 않기 때문이다(state는 여러개 선언하면 각자 독립적으로 작동하므로-Component instance별로 각각의 state를 사용하기 위해 이렇게 해놨을거라고 추측). 새로운 state가 업데이트 될 뿐 업데이트 되지 않은 key값은 버림
이럴때 보통 spreed문법을 써서
setLogiinInfo({ ...loginInfo, userEmail: event.target.value })
이런식으로 해주는데 특정한 경우에한해서는 이게 안되는 경우가 있다.
위의 경우는 상태를 업데이트 할때마다(whenever you update state you depend on previous state) 이전state(...loginInfo)에 의존하여 상태를 업데이트 하고 있음
이전 state의 snapshot을 이용하여 기존값에 복사하고 그리고 새로운 값(event.target.value)을 겹쳐쓴다.
이러한 방식의 문제점은 이론적으로 동시에 많은 수의 state업데이트를 계획한다면 오래되거나 잘못된 snapshot에 의존하게 될 수도 있다.
해결방법
setState((prevState)=>{
return {...prevState, 새함수}})
이런식으로 setState안에 함수를 넣어주면 리엑트에 의해 state안의 함수가 자동으로 실행됨. 그리고 항상 최신의 state snapshot이라는걸 리엑트가 보장함. 리엑트가 모든 계획된 상태 업데이트를 기억하고 있으므로
**
스테이트를 업데이트 하는 함수를 사용 할 때 ,이전 상태에 있는 무언가를 기준으로 값이 변경된걸 업데이트 할 때, 즉
컴포넌트 안에 있는 스테이트를 이용해서 업데이트하면, 업데이트 시점에 있는 스테이트가 오래된 거일 수도 있음
-즉 동기적으로 할 수 없을 때도 있음해결방법: 다음과 같이 컴포넌트에 있는 state값{...cards} 에 의존해서 값을 변경해서 setCards로 업데이트 하는 것이 아니라 setStateAction 을 사용//이전의 상태값을 받아서 새로운 상태값을 리턴하는 콜백함수로도 사용하는게 확실하고 안전한 방법.
// Unlike the class component setState, the updates are not allowed to be partialtype SetStateAction<S> = S | ((prevState: S) => S);'React' 카테고리의 다른 글
useCallback (0) 2022.02.25 useMemo (0) 2022.02.20 UseEffect (0) 2022.01.13 Router (0) 2022.01.09 react router useNavigate() (0) 2022.01.05