Devlog 7일차 입력 1초 기다리고 서버 요청 😤

shleecloud·2021년 11월 21일
0

Codestates

목록 보기
73/95

들어가며

7일, 2주차 월요일 Devlog부터는 밀렸다. 이유는 손목 통증. 얼마나 오래 작업을 했으면 손목이 아파서 글조차 쓰지 못할 지경이었을까. 이 날 이후로 손목보호를 위해서 왼손 마우스로 전향했다. 밀려있는 devlog를 작성하려니 막막한 기분이 드는데 다행히 github에 작성해둔 간략한 devlog가 있어서 이걸 토대로 작성하려고 한다.

입력 1초 기다리고 서버 요청

팀원들의 코드와 진행 상황을 봐주고 저녁부터는 이 부분을 중점적으로 진행했다. 특히 이 기능에 많은 시간을 썼다. 여러가지 개념이 복합적으로 적용하는 부분이었다.
이 기능을 도입하면 불필요한 서버 중복 요청을 줄일 수 있다.

개념1. useEffect 환경에서 비동기 함수

결론부터 이야기하면 useEffect 함수에 바로 async를 씌울 수 없다.
예를 들어 useEffect(async () => { 이런 코드는 안된다.
이렇게! 비동기 함수를 따로 만들고 실행해야 된다.

useEffect(() => {
async function testFunc() {
  const A = await axios();
  console.log(A);
}
  testFunc();
}, [])
  • async await 함수는 프로미스 객체를 반환 하므로 부수효과 함수가 될 수 없다.
  • 부수 효과 함수는 함수만 반환 할 수 있으며, 반환된 함수는 부수 효과 함수가 호출되기 직전과 컴포넌트가 사라지기 직전에 호출된다.
  • useEffect 훅에서 async await 함수를 사용하는 한 가지 방법은 부수 효과 함수 내에서 async await 함수를 만들어서 호출하는 것

[Hooks] useEffect 비동기 사용하기
[react] useEffect 훅에서 async await 함수 사용하기

useEffectuseState 개념은 어느정도 알겠는데 여기에 비동기를 끼얹으니 엄청나게 햇갈렸다. 지금 시점에선 async/await 다루는 법이 능숙해졌지만 이 당시에는 간신히 찾아가면서 했다. 작업시간이 길어지면서 피로감이 쌓였었나. 비동기 코드를 조금이라도 보고 왔었으면 어땠을까?

개념2. setTimeout, clearTimeout

setTimeout 첫번째 인자로 서버에 중복 확인 요청 함수를 배치하고 두번째 인자로 시간을 배치한다. 텍스트 박스에 onChange 작업이 발생하면 setTimeout 시간(1초)를 clearTimeout 으로 초기화하고 다시 setTimeout을 실행한다.

여기서 문제가 생기는데 onChange를 받는 Hook이 갱신되면서 새로운 setTimeout이 만들어진다. clearTimeout을 실행해도 새로운 랜더링 환경에서 실행되기 때문에 완전히 새로운 setTimeout을 초기화하게 된다. setTimeout이 랜더링 되더라도 남아있어야 된다고 판단해서 다시 구글링을 돌렸다.

개념3. useRef()

useRef는 랜더링이 다시 되더라도 상태를 가지고 있을 수 있다. timeWait라는 변수에 useRef() Hook을 할당하고 clearTimeout과 setTimeout을 걸어놨다. 결과는 대성공! 새롭게 랜더링 되더라도 useRef 때문에 이전 setTimeout이 성공적으로 남아있으면서 초기화된다.

 // TODO: 입력시 대기 후 서버에 데이터 충돌 확인
  const timeWait = useRef();
    useEffect(() => {
    clearTimeout(timeWait.current);
    timeWait.current = setTimeout(() => {
      // * useEffect 안에서 비동기 실행할 때 함수
      async function setConflictationMsgFromAsync() {
        setConflicationMsg(await isConflict(values));
      }
      setConflictationMsgFromAsync();
      setValidationMsg(isValid(values));
    }, 1000);
  }, [values]);
profile
블로그 옮겼습니다. https://shlee.cloud

0개의 댓글