2023-01-08 PM 07:52
Start
기획했던 대로 파일부터 나누어 보았다
파일만 나누었을 뿐 내용은 텅 비어있는 껍데기 파일일 뿐이다
(사진으로만 보면 어려울 수도 있으니 Github 주소를 첨부 : https://github.com/juuuuung/Instagram_clone)
로그인/가입 변경 버튼
"이걸 먼저 구현해 두어야 편하지 않을 까?" 하는 생각으로 우선순위 1번으로 정했다
문제들
useState를 사용하여야 겠다고 생각한 뒤 나는 순조롭게 진행해 가고 있었다.
그런데 한 가지 문제가 발생한다 Component를 너무 잘게 쪼개 버려서 prop drilling 이 문제가 되어 버렸다....(っ °Д °;) っ
그래서 상태관리 라이브러리 Jotai를 공부하기 시작했다
https://github.com/pmndrs/jotai
문법만 대충 알아보고 React 프로젝트에 적용해 보았다.
말도 안 되는 경험을 했다.
" 오.... 싯!@@ 이게 Jotai?? "
Jotai를 쓰지 않았다면 조금 과장해 수백 개의 하위 컴포넌트를 타고 Prop을 전달해 줘야 했을 터이지만
Jotai는 내가 그러는 걸 원치 않았다
jotai의 추가로 인한 상태관리의 효율을 위해 새로운 폴더 Store을 src 아래 만들었다
// src/store/Join.ts
import { atom } from "jotai";
export const show_login = atom(true);
일단 이렇게 전역으로 보낼 수 있는 상태는 만들었고 이젠 버튼 누르면 false로 바뀌게 만들어야겠다
위 사진을 컴포넌트로 만들어야겠다
파일 이름은 Selectview.tsx 자신의 목적에 맞는 이름은 아니지만 뭐라 적어야 할지 몰라서 이렇게 작성했다
밑은 파일 안에 적힌 코드이다
// src/components/molecules/Selectview.tsx
import Button from "../atoms/Button";
import { useAtom } from "jotai";
import { show_login } from "../../store/Join";
export default function Selectview() {
const [, setShow] = useAtom<boolean>(show_login);
return (
<div>
<p>계정이 없으신가요?</p>
<Button text="가입하기" state={setShow} />
</div>
);
}
show_login은 위에 상태관리 파일 Join.ts에 적어둔 것을 말한다
useAtom을 통해 show_login을 setShow로 만들어 준다 그리고 처음에 만들어둔 atoms/Button.tsx 에 props를 보내준다
밑은 Button.tsx의 코드이다
// src/components/atoms/Button.tsx
import { Dispatch, SetStateAction } from "react";
interface props {
text: string;
state?: () => void;
}
export default function Button({ text, state }: props) {
return (
<div>
<button
onClick={() => {
// ERROR!!!!
state && state((prev) => !prev);
}}
>
{text}
</button>
</div>
);
}
자.... 여기서 문제가 나타난다 맨 위의 interface props를 보면
" 어라.... setState는 함수이긴 한데.... void 주면 안 되나? "
ERROR : Expected 0 arguments, but got 1. (함수가 원하는 인자는 0개이지만 1개의 인자가 있습니다.)
왜 계속 에러가 나는 것일까, 난 StackOverFlow에 검색하기 시작한다 How to use setState in typeScript, typescript in setState 되지도 않는 문법으로 열심히 검색한 결과 구글링을 통해 알 수 있었다 ψ(._. )>
import { Dispatch, SetStateAction } from "react";
type Dispatcher<S> = Dispatch<SetStateAction<S>>;
interface props {
text: string;
state?: Dispatcher<boolean>;
}
export default function Button({ text, state }: props) {
return (
<div>
<button
onClick={() => {
state && state((prev) => !prev);
}}
>
{text}
</button>
</div>
);
}
useState를 정의할 수 있었던 것이다 오 싯....!
문제를 해결을 하고 Join Component에 true일 때 로그인 화면 false일 때 회원가입 화면을 만들어 주었다
// src/pages/Join.tsx
import Adlist from "../components/molecules/Adlist";
import Selectview from "../components/molecules/Selectview";
import Login from "../components/organisms/Login";
import Signup from "../components/organisms/Signup";
import { show_login } from "../store/Join";
import { useAtom } from "jotai";
export default function Join() {
const [show] = useAtom(show_login);
return (
<div>
{show ? <Login /> : <Signup />}
<div>
<Selectview />
</div>
<div className="ad">
<Adlist />
</div>
</div>
);
}
진척도는 0.3% 정도 늘지 않았을까
결과
오늘 얻은 교훈
UseState에서 SetState가 Type으로 정의가 가능했다니....
typeScript를 사용하여 react 프로젝트를 진행하고 있지만 TypeScript 사용을 props 전달할 때 interface로만 사용하니 너무 아쉽다 TypeScript의 적극 활용을 위해 더 알아봐야겠다
다음 할 것
Login Component의 뼈대는 다 만들었으니 Signup Component의 뼈대를 만들어 보아야겠다