이번 프로젝트에서는 처음으로 Recoil , TS를 사용하여 프로젝트를 진행하고 있다.
현재 전체적인 Layout을 TS를 통하여 만들었고 Recoil을 이용하여 일기 쓰기 페이지를 작성해 보았다.
해당 페이지의 코드는 다음과 같다.
import React from "react";
import axios from "axios";
import { useRecoilState } from "recoil";
import { journalState } from "../../Atom";
import { JournalPostMain, JournalPostSC, ButtonDiv } from "./JournalPostSC";
const JournalPost : React.FC = () => {
const [journal, setJournal] = useRecoilState(journalState);
const handleSubmit = async (e : React.MouseEvent) => {
e.preventDefault();
try {
await axios.post('URL', {journal})
alert('작성이 완료 되었습니다!')
} catch(err) {
console.log(err)
alert('다시 작성해 주세요.')
}
}
return(
<JournalPostMain>
<h1>EEUM : 하루 일기</h1>
<JournalPostSC>
<textarea
autoFocus
placeholder = "일기를 적어주세요"
value = {journal}
onChange = {(e : React.ChangeEvent<HTMLTextAreaElement>) =>
setJournal(e.target.value)
}
/>
</JournalPostSC>
<ButtonDiv>
<button onClick = {handleSubmit}>일기 작성</button>
</ButtonDiv>
</JournalPostMain>
)
}
export default JournalPost;
해당 페이지를 작성 하면서 구상한 코드 구조는
1. Recoil을 활용 하여, atom에 journalState를 선언
// src/Atom.ts
import { atom } from 'recoil';
export const journalState = atom({
key : 'journalState',
default : ''
});
따라서 어떤 컴포넌트여도 journalState를 import하여 사용 할 수 있다.
// App.tsx
import React from 'react';
import Main from './Page/Main/Main';
import { BrowserRouter } from 'react-router-dom';
// 20230421 이효상 recoil import
import {
RecoilRoot,
atom,
selector,
useRecoilState,
useRecoilValue,
} from 'recoil';
const App : React.FC = () => {
return (
<RecoilRoot>
<BrowserRouter>
<Main/>
</BrowserRouter>
</RecoilRoot>
);
}
export default App;
그 이유는 App.tsx에서 App을 export하여서 렌더 할때 최상단 컴포넌트로 RecoilRoot로 감싸 주었기 때문이다.
2. useRecoilState로 atom의 journalState값 변경
useState 훅 대신 useRecoilState를 사용하여 atom의 journalState 값을 변경 할 수 있도록 로직을 짜서 Recoil을 활용 하였다.
현재 타입스크립트로 구조를 짜면서 event들의 타입들을 일일히 설정하는 것에 난항을 겪었으나,
해당 코드 구조로
아직 API의 명세가 없기 때문에 axois async await문에서 catch 구문까지 가는 것을 확인 하였으며,
추후 API 명세가 나오면 추가로 개발 진행 예정이다.