해결된 질문
작성
·
49
0
안녕하세요! 강의 잘 듣고 있습니다.
제가 혼자 실습하다가 createPostAction
의 반환값에 success
필드를 넣은 후에 useActionState
의 initialState
에도 이 필드를 아래와 같이 추가했었는데요,
const [state, formAction, isPending] = useActionState(createPostAction, {
message: '',
errors: {},
formData: {
title: '',
tag: '',
content: '',
},
success: false,
});
useActionState
훅을 사용할 때 initialState
에 포함된 필드 중 일부를 이후 action
함수의 반환값에서 생략하면 어떤 경우에는 에러가 발생하고, 어떤 경우에는 아무 문제 없이 동작하는 게 잘 이해가 되지 않아서요. 예를 들어 initialState
에는 success
필드가 있지만, 유효성 검사 실패 시 반환 객체에서 success
를 생략하면 에러가 발생합니다.
if (!validatedFields.success) {
return {
errors: validatedFields.error.flatten().fieldErrors,
message: 'Validation failed',
formData: rawFormData,
success: false, // 없으면 useActionState 에서 에러 발생
};
}
그런데 try...catch
문에서는 success
없이 반환하면 에러가 발생하지 않는 걸 확인할 수 있었습니다.
try {
const { title, tag, content } = validatedFields.data;
await createPost({ title, tag, content });
revalidateTag('posts');
return {
success: true, // 없어도 에러 안남
message: 'Post created successfully',
};
} catch (e) {
return {
message: 'Failed to create post : ' + e,
formData: rawFormData,
};
}
formData
필드도 비슷하게 행동하는데 이 차이가 왜 발생하는지, 어떤 기준으로 반환 객체의 필드 구조를 검사하고 에러를 발생시키는지 궁금합니다. useActionState
에서 반환 객체의 필드가 initialState
와 구조적으로 정확히 일치해야 하는 조건이 언제 적용되는 건가요?
답변 2
1
이건 TypeScript의 타입 추론 방식 때문인 것 같습니다.
추측해보면:
if
문은 TypeScript가 정적 분석할 수 있어서 반환 타입을 엄격하게 검사하는 것 같고
try-catch
는 런타임에만 실행되다 보니 TypeScript가 catch 블록의 타입 검사를 덜 엄격하게 하는 것 같습니다
또 다른 가능성:
useActionState
의 초기 state 타입 추론이 첫 번째 반환값을 기준으로 고정되는 것일 수도 있고
컴파일러가 실행 경로별로 다르게 타입 검사를 하는 것일 수도 있습니다
정확한 이유는 React나 TypeScript의 내부 구현을 봐야 알 것 같은데, 안전하게는 모든 반환 객체에서 같은 필드 구조를 유지하는 게 좋을 것 같습니다~!
0
안녕하세요, 인프런 AI 인턴입니다.
질문 주신 내용은 React의 커스텀 Hook인 useActionState
에서 반환값의 필드 구성과 오류 발생에 관한 것입니다. 여기서 핵심은 언제 필드의 생략이 오류를 초래하는지에 대한 것입니다.
useActionState
와 같은 커스텀 Hook에서는 일반적으로 initialState에 정의된 상태의 구조를 기반으로 상태 업데이트를 처리합니다. 여기서는 다음과 같은 이유로 에러가 발생하거나 발생하지 않을 수 있습니다:
명시적인 상태 정의: initialState에 포함된 모든 필드를 응답 객체에서도 일관되게 관리해야 하기 때문에 필드가 예상되지 않는 경우에 오류가 발생할 수 있습니다. success
필드를 함수가 생략한 경우라면, initialState
나 함수를 호출하는 곳에서 해당 필드에 대한 처리가 없을 때 예상치 못한 동작이나 에러가 발생합니다.
필수 필드: 특정 상황에서 특정 필드가 필수적인 경우(예: success
필드는 성공 여부를 알려주기 위해 사용), 그러한 필드가 생략되면 로직 상에서 문제가 발생할 수 있습니다. 반면, try...catch
문에서는 예외가 발생할 때 특별히 사용되지 않는 경우도 있지만, catch
블록이 모든 예외를 포괄하도록 설계된 경우라면 문제가 발생하지 않습니다.
조건적 반환 로직: 성공과 실패를 구분하는 조건문(logic gate)은 success
가 각각 다르게 처리되기 때문에 반환되는 구조가 다를 수 있습니다. try
블록 내에서는 success
가 없더라도 특별히 참조되지 않는 경우에 한해 에러가 발생하지 않을 수 있습니다.
결론적으로, useActionState
의 경우 초기 상태 및 로직 전체에서 어떤 필드가 필수인지, 상태 업데이트의 로직을 어떻게 구성하는지에 따라 필드 생략으로 인해 발생할 수 있는 에러를 줄일 수 있습니다.
이와 관련된 기존 답변과 설명을 안내드립니다.
이 게시물에서는 비슷한 개념과 로직에 대해 다룬 내용을 찾을 수 있습니다.
저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다. 현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏 추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.