react
typescript
type LoginSuccessMessage = "SUCCESS";
type LoginFailMessage = "FAIL";
interface LoginRes {
message: LoginSuccessMessage | LoginFailMessage; // "SUCCESS" | "FAIL"
token: string;
}
interface UserInfo {
name: string;
}
interface User {
username: string;
password: string;
userInfo: UserInfo; // string타입
}
const users: User[] = [
{ username: "hello", password: "1234", userInfo: { name: "강코딩" } },
{ username: "world", password: "qwer", userInfo: { name: "나해커" } },
{ username: "bye", password: "!@#$", userInfo: { name: "남궁버그" } },
];
login 함수는 비동기함수이다. 올바른 username, password를 입력받았을때 LoginRes를 리턴한다. 목데이터에 없는 username과 password를 리턴하는 경우에는 null을 리턴하게 된다.
여기서 토큰이라고 보낸 건 임의로 작성된 것으로 실제로 이렇게하면 아마 큰일나지 않을까..
const login = async (
username,
password
): Promise<LoginRes | null> => {
const user: User | undefined = users.find((user) => {
return username === user.username && password === user.password;
});
if (user) {
return {
message: "SUCCESS",
token: JSON.stringify({ user: user.userInfo, secret }),
};
} else {
return null;
}
};
event: React.FormEvent<HTMLFormElement>
FormData()
input에서 값을 받아올 때 e.value로 항상 받아왔었는데 FormData라는 것이 있다. 코드가 간결해져서 넘 좋음. 그런데 유효성검사는 즉각적으로는 못하는듯? useRef를 쓸때처럼 사용해주어야 할 것 같다. (focus가 해제됐을때 값을 가져와서 검사하고 메세지를 띄우는 형식)
사용법
1. input에 name을 준다.
formdata를 읽어올때 name을 키로 받아온다.
2. formData 객체를 만든다.
const formData = new FormData();
3. formData.get("name")
input name을 get 메서드로 보내주면 값을 읽어온다.
4. formData.append("name", "value")
값을 추가할 수도 있다.
5. 이외에도 많이있음.
keys, set, getAll, delete,
entries({key:"value"}[] 형태의 iterator 반환),
has(특정 키가 있는지 여부 반환), values...
button vs input type="submit"
button의 디폴트 타입은 submit이다.
둘다 같은 기능을 가지고 있다. 찾아봤을때 딱히 다른 점은 없는 것 같은데,
input과 button이 같은 타입을 공유하고 있는 것으로 보인다.
input으로도 button, reset, submit을 만드는 것이 가능하다.
다만 내 생각에는 input으로 했을때보다 button으로 했을 때 좀더 의미가 와닫을것같다.
const Login = () => {
const [userInfo, setUserInfo] = useState<UserInfo>();
const loginSubmit = async (
event: React.FormEvent<HTMLFormElement>
) => {
event.preventDefault();
const formData = new FormData(event.currentTarget); //formData 객체 생성
const loginRes = await login(
formData.get("username") as string,
formData.get("password") as string
); //as로 타입스라이팅(?)을 하지않으면 에러가 난다. ㅠㅠ 왜인지 알려주실분
if (!loginRes) return;
};
return (
<div>
<h1>Login with Mock API</h1>
<form onSubmit={loginSubmit}>
<label>
Username:
<input type="text" name="username" />
</label>
<label>
Password:
<input type="password" name="password" />
</label>
<button>submit</button>
</form>
<div>
<h2>User info</h2>
{JSON.stringify(userInfo)}
</div>
</div>
);
};
const getUserInfo = async (token: string): Promise<UserInfo | null> => {
const token = JSON.parse(token);
if (!token?.secret || token.secret !== secret) return null;
const loggedUser: User | undefined = users.find((user: User) => {
if (user.userInfo.name === token.user.name) return user;
});
if (loggedUser) {
return loggedUser.userInfo;
} else {
return null;
}
};
getUserInfo를 실행해 usrInfo에 저장한다.
const Login = () => {
const [userInfo, setUserInfo] = useState<UserInfo>();
//... 생략
const userInfo = await getUserInfo(loginRes.token);
if (!userInfo) return;
setUserInfo(userInfo);
}
이렇게 간단하게(?) 로그인을 구현해보았다. 사실 이때 첫 한시간을 못들어서... 😭
혼자 강의자료를 보면서 연습해봤다. 그래서 다르거나 틀린 부분이 있을 것 같음.
이번 강사님은 말씀도 너무 잘하시고 답변도 잘해주시고 역시 대기업의 배포(?)가 느껴진다.ㅋㅋㅋㅋㅋ
그리고 너무 유익함!!
무엇보다 타입스크립트를 공부하고 강의를 듣게 되어서 너무나도 다행이었다!
타입스크립트때문에 어려워하는 분들이 많은 것 같음. 코드가 깔끔하고 이해하기 쉽게 되어있어서 정말 도움된다.
그래서 나는 그래도 이해는 쭉쭉 된다.. 이렇게 내가 구현할수있는지와는 별개로ㅎㅎ
열심히 기록하고 연습해서 내껄로 만들어야지. 💪