강의

멘토링

커뮤니티

Cộng đồng Hỏi & Đáp của Inflearn

Hình ảnh hồ sơ của devong
devong

câu hỏi đã được viết

Những điều họ không nói với bạn trong bootcamp (React) Phần 1

마지막 onSubmit 에러체크 문제

Đã giải quyết

Viết

·

379

1

  • 에러체크할 때 나머지값이 없어도 submit이 되는 문제가 있습니다.

<InfoContext.Provider value={{ value: info, setValue: setInfo, error, setError: (e) => setError({...error, ...e}) }}>
      <Form onSubmit={onSubmit}>
        <TextField
          source="name"
          label="이름"
          validate={[minLength(3), maxLength(6)]}
        />
        <TextField
          source="password"
          label="패스워드"
          validate={[minLength(6), maxLength(12)]}
        />
        <CheckboxField
          source="confirm"
          label="위 내용이 제출됩니다 동의하십니까?"
          validate={[checked]}
        />
      </Form>
    </InfoContext.Provider>

위 코드에서 setError update해주는 로직을

// before
setError: (e) => setError({...error, ...e})

// after
setError: (e) => setError(prev => ({...prev, ...e}))

아래와 같은 형식으로 바꿔주면, 리팩토링 이전과 같이 동작을 하게됩니다.

batch의 문제인지, 불변성의 문제인지 정확히 모르겠네요.

설명해주시면 감사감사!

reacttddReact-Contextjest소프트웨어-테스트

Câu trả lời 1

2

aftercamp님의 프로필 이미지
aftercamp
Người chia sẻ kiến thức

안녕하세요 구스타프님!

엄청 좋은 질문을 해주셨네요! batch까지 의심하셨다니 내공이 조금 있으시군요

"batch 문제일 것이다" 라는 가설을 검증하기 위해서 상태 업데이트를 순차적으로 실행하도록 해봤는데요.

useInput.tsxuseEffect에서

setTimeout(() => setError({ [source]: err } as PartialErrorInfo), 0);

로 변경하거나

queueMicrotask(() => setError({ [source]: err } as PartialErrorInfo))

상태변경이 batch 로 동작하지 않도록 해도 말씀하신대로 submit 이 동작합니다. 따라서 batch 문제는 근본적인 문제가 아닌 것 같고..

하지만

말씀하신대로 setError에 함수를 넘겨서 previous state를 사용하면 정상 동작하게 되는데, 그 이유는

useInputuseEffect 가 각 필드 TextField, CheckboxField 에서 독립적으로 실행됩니다.

context에 넘겨주는 setError 함수 내부에선 error의 값이 모두 undefined입니다.

setError: (e) => {
// 3개의 각 필드에서 실행되는 시점에 error는 {name: undefined, password: undefined, confirm: undefined}
  setError({ ...error, ...e }); 
}

그래서 구체적으로 error 상태가 어떻게 업데이트가 되냐면

setError({ name: “최소 3자 이상 입력해주세요", password: undefined, confirm: undefined})
setError({ name: undefined, password: “최소 6자 이상 입력해주세요", confirm: “반드시 체크해주세요”})
setError({ name: undefined, password: undefined, confirm: “반드시 체크해주세요”})

이 순서대로 실행되고 마지막으로 실행된 confirm에 대한 에러만 보이게 되는 것입니다.

App.tsx의 CheckboxField 컴포넌트 위치를 Password 텍스트 필드 위로 올리고 새로고침하면 마찬가지로 Password 에러만 나타나게 됩니다.

따라서 제안해주신 방법대로 previous state 를 이용해야 위와 같은 문제가 발생하지 않을 것입니다.


아무튼 이것과 관련해서 강의 내 오류가 있는 부분은 정정하도록 하겠습니다!

감사의 의미로 제 메일 주소로 morishjs@gmail.com 연락처 남겨주시면 감사의 선물을 보내드리겠습니다 🙇‍♀️

devong님의 프로필 이미지
devong
Người đặt câu hỏi

아 `독립적으로 실행` ... 맞네요!

답변 감사합니다! 😊

Hình ảnh hồ sơ của devong
devong

câu hỏi đã được viết

Đặt câu hỏi