firebase authentication에서 github 활성화 클릭!
-> github application 정보가 필요함
github에서 new OAuth application 생성하기
반환받은 client id를 fb에 붙여넣기
Generate a new client secret
// ✅ github-button.tsx - nwitter 클론코딩
import {
GithubAuthProvider,
signInWithPopup,
// signInWithRedirect,
} from "firebase/auth";
import styled from "styled-components";
import { auth } from "../firebase";
import { useNavigate } from "react-router-dom";
const GithubButton = () => {
const navigate = useNavigate();
const onClickHandler = async () => {
try {
// 🧡 github로그인을 위한 provider 생성 'GithubAuthProvider()'
const provider = new GithubAuthProvider();
// 🧡 1. Popup으로 로그인하기
await signInWithPopup(auth, provider);
// 🧡 2. 다른페이지로 이동해서 깃헙로그인하기
// await signInWithRedirect(auth, provider);
// 로그인 성공하면 홈으로 이동
navigate("/");
} catch (error) {
console.log(error);
}
};
return (
<Button onClick={onClickHandler}>
<Logo src="/github-mark.svg" />
Continue with Github
</Button>
);
};
export default GithubButton;
비동기 함수의 type 형식은 Promise< T >
형식!
👍🏻 올바른 type형식 코드
export const getTodo = async (): Promise<Todo[]> => {
const res = await todoClient.get("/");
return res.data;
};
// void인 경우도 마찬가지!
export const addTodo = async (newTodo: Todo): Promise<void> => {
await todoClient.post("/", newTodo);
};
'Todo[] | undefined' 형식에는 반복기를 반환하는 '[Symbol.iterator]' 메서드가 있어야 합니다.
오류메시지 발생원인 : useQuery 훅에서 데이터를 가져오기 전에 todos가 undefined일 수 있기 때문에 이런 경고가 발생
해결
// ✅ TodoLists.tsx - todoList typescript 리팩토링 개인과제
// useQuery로 가져오는 값의 Type 정해주기
interface TodosType {
// data가 들어오기 전에는 undefined일 수도 있으니 함께 작성
data: Todo[] | undefined;
isLoading: boolean;
isError: boolean;
}
const TodoLists: React.FC = () => {
const [sortOrder, setSortOrder] = useState("asc");
// ⭐️ useQuery로 불러오는 값에 type지정하기!
const {
data: todos,
isLoading,
isError,
}: TodosType = useQuery({
queryKey: ["todos"],
queryFn: getTodos,
});
// loading, error 처리
if (isLoading) {
return <div>Loading...</div>;
}
if (isError) {
return <div>Error</div>;
}
const onSortChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
setSortOrder(e.target.value);
};
// ⭐️ todos가 아직 없는 경우도 생각해서 삼항연산자 작성!
// 이 부분을 그냥 [...todos]로 시작했더니 위와 같은 오류메시지 발생함
const sortedTodos = todos
? [...todos].sort((a, b) => {
if (sortOrder === "asc") {
return new Date(b.deadline) - new Date(a.deadline);
}
return new Date(a.deadline) - new Date(b.deadline);
})
: [];
// ...생략
// ✅ InputBox.tsx - todoList ts로 리팩토링
const InputBox: React.FC = () => {
const onSubmitHandler = (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
// ⭐️ e.target.title.value 형식이었는데 ts에 맞게 수정!
// get을 타고 들어가보면 string | file 이라고 나옴
// type="text"해놨기 때문에 as string으로 type정해버리기
const formData = new FormData(e.currentTarget);
const title = formData.get("title") as string;
const content = formData.get("content") as string;
const deadline = formData.get("deadline") as string;
const newTodo: Todo = {
id: Date.now().toString(),
title,
content,
isDone: false,
deadline,
};
e.currentTarget.reset();
};
return (
<St.Container>
<St.Title onSubmit={onSubmitHandler} name="hello">
<St.TitleInput name="title" placeholder="제목" />
<St.TitleInput name="content" placeholder="내용" />
<St.Time>
<label htmlFor="start">마감일 :</label>
<St.TimeInput
type="date"
id="start"
name="deadline"
min="2024-01-01"
max="2026-12-31"
/>
</St.Time>
<div className="addBtn">
<St.AddBtn type="submit" className="btn text-white">
추가하기
</St.AddBtn>
</div>
</St.Title>
</St.Container>
);
};
export default InputBox;