자, 이제
이 섹션이 거의 마무리되가고 있습니다
하지만 한 가지 더 상태와 관련된 개념이 남아있습니다
이 강의에서 꼭 다루어야 하는 내용인데
그건 바로, 상태 업데이트 내용의 실행 일정이
리액트에서 어떻게 조정되고 실행되는지에 대해서 입니다
이전 강의에서도 말씀드렸듯이
상태 업데이트 함수를 불러오면
예를 들어 setChosenCount가 있습니다
그럼 상태 업데이트는 리액트로부터 일정이 조정됩니다
즉 즉각 실행되지 않습니다
그래서 업데이트 한 직후 상태를 console.log로 보면
새로운 상태는 보이지 않고
이전 상태만 보입니다
그리고 이건 사람들이 오해하는 부분 중 하나입니다
즉 상태를 한 줄로 업데이트한다고 생각하고
그리고 다음 줄에서 업데이트된 상태를 사용할 수 있다고 생각하지만
그렇게 작동하지 않습니다
콘솔을 열고 이걸 지우고
새로운 상태를 설정해보겠습니다
여기 보이시듯 이전 상태가 있는데
이건 리액트가 상태 업데이트의 스케줄을 조정하기 때문입니다
그리고 결국에는 꽤 즉각적으로
실행될 것이지만
바로 실행되지는 않을 겁니다
그리고 한순간 이전 컴포넌트 함수 실행에 속한
값이 바뀌지도 않을 것입니다
대신 이것은
새로운 컴포넌트 함수 실행을 야기하고
다음 실행을 위한
새로운 상태가 준비될 것입니다
하지만 그 상태 업데이트들에는 실행 일정이 따로 있기 때문에
이전 상태 값에 의존하는 상태 업데이트를 수행하기 위해
이러한 함수 형태를 사용하는 것이 가장 좋은 방법입니다
이전 강의에서도 보여드렸었죠
상태를 업데이트하는 함수에게 함수를 전달하면
그 함수가 이전 상태 스냅샷(snapshopt)을 받고
새로운 상태 스냅샷을 반환합니다
이전 상태 스냅샷을 사용해서
새로운 스냅샷을 전달할 수 있습니다
이 접근 방식을 사용할 땐
리액트가 여기서
가장 최신 상태 스냅샷을 보장하기 때문에
만약 여러 상태 업데이트가 동시에 생긴다면
스케줄된 순서대로
실행될 것입니다
그리고 여기에는 항상 올바른 값만 받을 겁니다
예를 들어, 어떤 이유로든
chosenCount를 업데이트하고 싶어서
1을 더해보면, 이상한 결과를 보게 됩니다
이런 식으로 하면 말입니다
newCount에 chosenCount를 지정하고
1을 더했을 때의 경우입니다
지금 이건 이전 상태를 사용하고 있기 때문에
newCount +1과 같은 결과는 받지 못합니다
대신 이전 상태 +1이라는 결과를 얻죠
그렇게 하고 여기 10을 클릭하면
여기선 1이 새로운 initialCount 값이 됩니다
왜냐하면 1이 저의 이전 chosenCount 값이 더해졌으니까요
이전 값은 0입니다
만약에 이 함수 형태를 쓴다면
이전 chosenCount를 받아서
자동으로 리액트에게 전달하고, 그 다음 1을 더해줍니다
그럼 비로소 newCount + 1을 얻을 수 있습니다
이제 두 상태의 업데이트 모두 스케줄이 조정되었고
실행되기를 보장되었기 때문입니다
조정된 순서대로입니다
하지만 두 번째 상태 업데이트는
예정된 업데이트가 실행될 때
그 시점의 최신 상태 값을 받습니다
그러므로 그때 받는 newCount값은
이 상태 업데이트에서 설정된 값입니다
그럼 코드를 수정해서 저장하고 새로고침 후
여기 10을 입력하면, 예를 들어 여기 11을 받습니다
그리고 이건 굉장히 중요한 작동 방식입니다
특히나 기억해야 할 것은
이 새로운 상태 값은
이렇게 설정한 직후에는 사용할 수 없습니다
그렇게는 작동하지 않습니다
적어도 여러분이 예상하는 대로 작동하지 않습니다
이 상태 스케줄 조정에서 중요한 것은
여러 상태 업데이트가 있고
동시에 실행되어야 한다면
그러니까 이렇게 같은 함수 안에서 실행되어야 한다면
아무튼 여러 컴포넌트가 동시에 실행되지 않을 것입니다
그건 당연히 비효율적이기 때문입니다
하지만 따지자면 그건
리액트가 신경 쓰지 않았을 때 생길 수 있는 일입니다
왜냐하면 우리는
두 개의 상태 업데이트 함수를 불러왔기 때문입니다
그러니까 배운 대로
상태를 업데이트하는 함수를 실행하는 건
컴포넌트 함수를 재실행하게 하고
컴포넌트 함수가 두 번 실행된다고 예상할 수 있습니다
상태 업데이트가 두 건이 있기 때문입니다
하지만 여기서 발생한 건 그게 아닙니다
콘솔을 열어 이걸 다 지우고 값을 입력한 다음
'설정'을 눌러보겠습니다
앱 컴포넌트는 한 번만 실행된 게 보이시죠?
딱 한 번만 불러졌고 두 번 불러지지 않았습니다
이게 바로 리액트가
상태 배칭(batching)을 한 것입니다
같은 함수 내에서
여러 상태 업데이트가 있을 때
다같이 배칭되어서
한 번의 컴포넌트 함수 실행을 유도합니다