handleSubmit을 다시 보자.
localState의 길이를 기준으로 0인지 아닌지를 판단하여 분기 처리하고 있다.
검색창에 입력값 'a'가 있음에도 아직 setLocalState가 반영되지 않았기 때문에, handleSubmit 함수가 호출돼서 입력값이 비었는지 확인하는 유효성 검사에서 빈 값(length === 0)으로 판정되어 'Please Enter github name.'이라는 메시지가 alert된다.
반면, input dom에 바로 접근하는 inputValue는 입력값을 그대로 반영한다.(53째 줄에 입력값 그대로의 검색 결과를 받아오기 위해 인수로 전달)
그 결과 다음과 같은 메시지가 콘솔에 출력된다.
왜 이런 현상이 발생한 것인지 setLocalState의 호출부를 가 보면 알 수 있다.
setLocalState와 비동기 api 요청 함수 handleSubmmit 이 같은 스코프 안에서 호출되고 있다.
그러면 state는 언제 업데이트 되는 것일까? 모른다. setState는 비동기함수이기 때문이다.
LocalState값 변경은 비동기적으로 일어나기 때문에, 그 아래 코드들은 그대로 실행되어 handleSubmit 함수를 호출하고, 아직 변경되지 않은 LocalState의 빈 값을 그대로 가져와서 실제 검색창에 입력 값이 있음에도 빈 값으로 판정되어 처리되는 것이다.
1. 그렇다면, LocalState가 변동되었을 때 handleSubmit 함수를 호출하면 어떨까?
useState 변수로 관리하고 있는 localState에 변동이 일어났을 때 handleSubmit 함수를 호출하면 되므로, useEffect() 등으로 처리할 수도 있다.
https://codingapple.com/unit/react-setstate-async-problems/
2. useState 훅을 동기적으로 작동시킬 수는 없을까?
useState 훅에 콜백함수를 전달하면 된다.
해당 콜백함수 안에서 handleSubmit 함수를 호출하면 변동된 값을 인수로 전달할 수 있다. (위 이미지에서 스코프만 달라졌다.)
34째 줄에서 첫 번째 인수의 값을 `null`로 전달하는 이유는 handleSubmit이
이벤트 객체를 받아 처리해야 하거나(정상적으로 검색 버튼 클릭, 엔터 등으로 'submmit'이벤트가 발생)
이벤트 발생없이 실행되어야하는 경우(타이핑을 끝내자마자 검색결과를 출력)
모두를 처리하고 있기 때문이다.
옵셔널체이닝으로 두 경우에 대한 예외처리를 했다.
60째 줄의 searchUsers는 삼항연산자로 타이핑일 경우와 submit 이벤트 발생일 경우로 분기 처리했다.
inputRef를 전달하지 않아도, 바뀐 상태의 값으로 호출을 잘 해오는 것을 확인할 수 있다.
위 이미지와 같이 여전히 inputRef.current.value 값과 변수 localState의 값은 동일하지 않지만, 요청을 새로 바뀔 값으로 보내고 있으므로 더 이상 입력값에 값이 있어도 늦은 동기화 때문에 빈 값으로 인식하고 잘못된 요청을 보내는 경우는 없다.