내가 짠 코드
1. userAddInfo
const UserAddInfo = () => {
const [userData, setUserData] = useState<UserData>({ nickname: "", birth: "", gender: "" });
const [step, setStep] = useState(1);
const [phone, setPhone] = useState("");
// 휴대폰 인증번호
const [phoneAuthNumber, setPhoneAuthNumber] = useState("");
// 휴대폰 번호 입력
const handlePhoneChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setPhone(event.target.value);
};
// 휴대폰 인증번호 입력
const handlePhoneAuthChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setPhoneAuthNumber(event.target.value);
};
// 전화번호 서버 전송
const phoneAuthPost = async () => {
try {
const phoneAuth = { phoneNumber: phone };
await axios.post("주소/api/verification-code", phoneAuth);
} catch (error) {
console.log(error);
}
};
// 번호인증 서버 전송
const phoneAuthPut = async (phoneAuthNumber: string) => {
try {
await axios.put(`주소/api/verification-code/${phoneAuthNumber}`);
} catch (error) {
console.log(error);
}
};
// 유저데이터 서버 전송
const userDataPost = async (userData: UserData) => {
try {
await axios.post(`주소/api/???/${phoneAuthNumber}`, userData);
} catch (error) {
console.log(error);
}
};
React.ChangeEvent<HTMLInputElement> : input 요소의 값이 변경될 때 발생하는 이벤트에 대한 타입
1) step 단계
2) 유저데이터(nickname, birth, gender) 전송
3) 휴대폰 인증 번호 전송
: 휴대폰 인증 번호를 PUT으로 전송한 이유는 인증번호가 새로 저장되는 것이아니라 "미인증"에서 "인증"으로 상태가 변한다.
return (
<>
<Wrapper>
<ContentBox>
<PreviousButton onClick={handlePreviousStepChange} step={step} />
</ContentBox>
{step === 1 ? (
<Nickname userData={userData} setUserData={setUserData} />
) : step === 2 ? (
<Gender userData={userData} setUserData={setUserData} />
) : step === 3 ? (
<PhoneNumber phone={phone} onChange={handlePhoneChange} />
) : (
<PhoneNumberAuth phone={phone} phoneAuth={phoneAuthNumber} onChange={handlePhoneAuthChange} />
)}
</Wrapper>
<NextButton onClick={handleNextStepChange} step={step} />
</>
);
const handleNextStepChange = () => {
if (step === 3) {
phoneAuthPost();
} else if (step === 4) {
phoneAuthPut(phoneAuthNumber);
userDataPost(userData);
}
updateStep(step + 1);
};
1) 각 스텝에 해당되는 컴포넌트를 보여준다
2) 이에 따라 필요한 데이터 전달
3) 스텝 3의 경우, 폰 번호 데이터 전송 (post)
4) 스텝 4의 경우 폰 인증번호 (get)와 유저 데이터 전송 (post)
① Step 단계마다 컴포넌트를 보여주는 것이 이뻐보이지 않는다.
2. Nickname
1) 작성하는 데이터 userData state에 저장
② 실시간으로 한글자 한글자 타이핑 치면서 업데이트 되는 것이 효율적인가 생각이 들었다. blur후 데이터가 업데이트 되는 것은 어떨까
닉네임 작성하는 부분이 짧아서 괜찮겠지만, 길어지면 문제가 좀 되지않을까?
const Nickname: React.FC<UserDataProps> = ({ userData, setUserData }) => {
const handleNicknameChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setUserData((prevUserData) => ({ ...prevUserData, nickname: event.target.value }));
};
return (
<>
<Wrapper>
<Question firstLine="반가워요!" secondLine="어떻게 불러드릴까요?" />
<InputType
type="text"
value={userData.nickname}
placeholder="닉네임을 입력해주세요"
onChange={handleNicknameChange}
text="* 2~16자의 한글, 영문, 숫자만 사용해주세요"
/>
</Wrapper>
</>
);
};
3. Gender
생일도 포함이 되지만 gender라는 이름은 맞지 않다
const Gender: React.FC<UserDataProps> = ({ userData, setUserData }) => {
const [gender, setGender] = useState<string>("");
//생일
const handleBirthdayChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setUserData({ ...userData, birth: event.target.value });
};
//성별 선택
const handleGenderChange = (selectedGender: string) => {
setUserData({ ...userData, gender: selectedGender });
setGender(selectedGender);
};
1) 생일 경우에는 선택 후, 바로 userData저장하고 userData.birth로 value를 설정
2) 성별의 경우, gender 선택 후 보여지는 button css를 위해 따로 gender state를 만듦
③ button css를 보여주기위해 추가적으로 gender를 만드는 거 말고 다른 방법이 없을까 고민이 됐다.
④ 그리고, 다음페이지로 이동했다가 돌아오니까 클릭했던 것이 풀려버리는 문제가 발생했다.
interface TypeButtonProps {
type: string;
setType: (type: string) => void;
selectedType: string;
}
const Button = styled.button<{ $selected: boolean }>`
flex-grow: 1;
border-radius: 15px;
height: 60px;
background-color: #fff;
/* color theme으로 수정 */
border: 1px solid ${({ $selected }) => ($selected ? "#0F62FE" : "#A2A9AD")};
color: ${({ $selected }) => ($selected ? "#0F62FE" : "#A2A9AD")};
`;
function TypeButton({ type, setType, selectedType }: TypeButtonProps) {
return (
<Button $selected={type === selectedType} onClick={() => setType(type)}>
{type}
</Button>
);
}
return (
<Wrapper>
<Question firstLine="oo님의" secondLine="생일과 성별을 확인해주세요" />
<InputType type="date" value={userData.birth} onChange={handleBirthdayChange} label="생일" />
<label>성별</label>
<TypeButtonBox>
<TypeButton type="남자" setType={(type) => handleGenderChange(type)} selectedType={gender} />
<TypeButton type="여자" setType={(type) => handleGenderChange(type)} selectedType={gender} />
</TypeButtonBox>
</Wrapper>
);
};
코드 수정
① Step 단계마다 컴포넌트를 보여주는 것이 이뻐보이지 않는다.
=> && 연산자를 사용하여 조건이 참일 때만 해당 요소를 렌더링하도록 했다!
{step === 1 && <Nickname userData={userData} setUserData={setUserData} />}
{step === 2 && <Gender userData={userData} setUserData={setUserData} />}
{step === 3 && <PhoneNumber phone={phone} onChange={handlePhoneChange} />}
{step === 4 && (
<PhoneNumberAuth phone={phone} phoneAuth={phoneAuthNumber} onChange={handlePhoneAuthChange} />
)}
④ 그리고, 다음페이지로 이동했다가 돌아오니까 클릭했던 것이 풀려버리는 문제가 발생했다.
=> 기본값으로 userData.gender를 사용
const [gender, setGender] = useState<string>(userData.gender || "");
'프론트엔드로 가는 길 > portfolio 제작 여정기 👩🏻💻' 카테고리의 다른 글
리쿠르탐_createBrowserRouter 적용 (0) | 2023.12.26 |
---|---|
petDairy_.env 파일 문제 (0) | 2023.12.24 |
1. UGSM_단계별 페이지 이동 (1) | 2023.12.21 |
01.PetDiary_카카오 소셜로그인 (2) | 2023.12.15 |
10. 자살예방웹사이트 - 속성오류 (2) | 2023.10.04 |