저번에 이어서 이번엔 제출버튼을 누르면 그 답으로 오게 만들어보겠다.
저번에 이어서 필요한 재료는 form-input 컴포넌트, submit 버튼, text를 담아줄 상태, 제출 핸들러가 필요하다.
useState를 써서 상태를 선언해주자.
const [promptValue, setPromptValue] = useState("");
이런 식으로 해서 파라미터 prompt에 인수로 넣어줄 텍스트 데이터를 만들어준다.
우선 텍스트의 값을 전달하는 모양새이기 때문에 form
태그를 이용해서 작성하겠다.
<form onSubmit={handleSubmit}>
<input type="text" value={promptValue} onChange={(e) => setPromptValue(e.target.value)} />
<button type="submit">Submit</button>
</form>
{/* <ChatResponse prompt={`Create 10 login related variable names with React`} /> */}
{promptValue && <ChatResponse prompt={promptValue} />}
제출 핸들러는 이후 기술할 거지만 일단 handleSubmit
으로 작성했고, promptValue
상태를 가져와 onChange
를 넣어 텍스트가 입력되고 promptValue
가 있다면 API 요청을 하여 목록을 가져오도록 했다.
handleSubmit
const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
};
event
에 타입 설정하고, 새로고침 방지하는 코드를 작성하려고 했다.
근데 입력하던 도중 어떻게 코드를 전개해야할지 고민했다.
입력하다 생각이 들었는데 handleSubmit
이란게 따로 없어도 되지 않나 싶었다. 왜냐면 {promptValue && <ChatResponse prompt={promptValue} />}
부분에서 promptValue
이 설정되면 결괏값이 나오도록 했기 때문이다.
그러면 핸들러를 빼고 그냥 해도 되지 않느냐? 싶지만 다시 생각해보면 매 입력때마다 API 호출을 한다는 뜻이다;; 그리고 만약 추후에 직접 입력을 하든, 내가 드롭다운 메뉴로 변수 생성을 위한 환경 설정을 매번 할 때마다 API 호출이 간다면 사이트 성능이 떨어질 것이어서 마음이 아플 것이다. 또 API 호출이 계속 이뤄지기에 내 지갑도 마음이 아플 것이다.
다양한 해결법을 생각해봤다.
input
상태를 제작해서 promptValue
상태는 제출할 때만 쓰기debounce
라이브러리를 써서 500ms마다 실행되게 하기input
에 onBlur
이벤트를 삽입해 포커스가 해제될 때 이벤트 설정하기 등등이 있는데 1번이 가장 깔끔하고, 상태의 변경이 제일 적어 쓸데없는 리렌더링이 덜 날 거 같아 1번으로 했다.
상태 추가, handleSubmit
수정, input
태그 속성 수정
const queryClient = new QueryClient();
const [inputValue, setInputValue] = useState("");
const [promptValue, setPromptValue] = useState("");
const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
if (inputValue !== "") {
queryClient.invalidateQueries("chatResponse");
setPromptValue(inputValue);
}
};
const ChatResponse = ({ prompt }: ChatResponseProps) => {
const { data, isLoading } = useQuery(["chatResponse", prompt], () => getChatResponse(prompt));
return isLoading ? <div>Loading...</div> : <div>{data?.resText}</div>;
};
return (
<>
<form onSubmit={handleSubmit}>
<input type="text" value={inputValue} onChange={(e) => setInputValue(e.target.value)} />
<button type="submit">Submit</button>
</form>
{promptValue && <ChatResponse prompt={promptValue} />}
</>
);
inputValue
상태로 모두 수정handleSubmit
조건이 충족되면 setPromptValue
부분을 inputValue
로 수정isLoading
을 넣어 로딩되는지 직접적으로 보여주기나중에 ChatResponse
는 useQuery
전용 컴포넌트로 분리를 해야겠다.
성공!
이제 다음 목차에선 직접 입력이 아닌 드롭다운 메뉴로 선택하여 더 편하게 변수를 생성하게 만들게 디자인 해보겠다.
완성이 거의 다돼가고 있군요 !! 저도 나중에 디바운스 써봐야겠어요 ㅎㅎ 잘봅고갑니다