โ๏ธ localStorage
- ์๋ก๊ณ ์นจํ๋ฉด ๋ธ๋ผ์ฐ์ ๋ html css js ํ์ผ๋ค์ ์ฒ์๋ถํฐ ๋ค์ ์ฝ๊ธฐ ๋๋ฌธ์ ๋ชจ๋ state ๋ฐ์ดํฐ๋ ๋ฆฌ์
๋๋ค.
- ์ด๊ฑธ ํด๊ฒฐํ๊ธฐ ์ํด์๋ state ๋ฐ์ดํฐ๋ ์๋ฒ๋ก ๋ณด๋ด DB์ ์ ์ฅํ๊ฑฐ๋ LocalStorage์ ์ ์ฅํ๋๋ฐ
- ์ค๋ ๋ฐฐ์ธ ๋ด์ฉ์ LocalStorage์ ๊ดํด์์ด๋ค.
- LocalStorage๋ ์ฝ๊ฒ ๋งํด ์ ์ ์ ๋ธ๋ผ์ฐ์ ์ ๋ชฐ๋ ์ ๋ณด๋ฅผ ์ ์ฅํ๊ณ ์ถ์ ๋ ์ฐ๋ ๊ณต๊ฐ์ธ๋ฐ ์ ์ ๊ฐ ๋ธ๋ผ์ฐ์ ์ฒญ์๋ฅผ ํ์ง ์๋ ์ด์ ์๊ตฌ์ ์ผ๋ก ๋จ์์๋ค.
- ์ฌ์ดํธ๋ง๋ค 5MB ์ ๋์ ๋ฌธ์์ด์ ์ ์ฅํ ์ ์๊ณ
- object ์๋ฃ์ ๋น์ทํ๊ฒ key/value ํํ๋ก ์ ์ฅํ๋ค.
โ๏ธ localStorage ๋ฌธ๋ฒ
- ๊ทธ๋ฅ js ํ์ผ ์๋ฌด๋ฐ์๋ ๋ค์ ๋ฌธ๋ฒ์ ์ฐ๋ฉด localStorage์ ๋ฐ์ดํฐ ์
์ถ๋ ฅํ ์ ์๋ค.
localStorage.setItem('๋ฐ์ดํฐ์ด๋ฆ', '๋ฐ์ดํฐ'); // ๋ฐ์ดํฐ ์ถ๊ฐ
localStorage.getItem('๋ฐ์ดํฐ์ด๋ฆ'); // ๋ฐ์ดํฐ ์ฝ๊ธฐ
localStorage.removeItem('๋ฐ์ดํฐ์ด๋ฆ') // ๋ฐ์ดํฐ ์ญ์
โ๏ธ localStorage์ array/object ์๋ฃ๋ฅผ ์ ์ฅํ๋ ค๋ฉด
- ๋ฌธ์๋ง ์ ์ฅํ ์ ์๋ ๊ณต๊ฐ์ด๋ผ array/object๋ฅผ ๋ฐ๋ก ์ ์ฅํ ์๋ ์๋ค.
- ๊ฐ์ ๋ก ์ ์ฅํด๋ณด๋ฉด ๋ฌธ์๋ก ๋ฐ๊ฟ์ ์ ์ฅํด์ฃผ๋๋ฐ ๊ทธ๋ผ array/object ์๋ฃ๊ฐ ๊นจ์ ธ์ ์ ์ฅ๋๋ค.
- ๊ทธ๋์ ํธ๋ฒ์ผ๋ก๋ array/object๋ฅผ JSON์ผ๋ก ๋ณํ์์ผ ์ ์ฅํ๋ค.
// array/object -> JSON
localStorage.setItem('obj', JSON.stringify({name:'kim'}) ); // "{"name":"kim"}"
// JSON -> array/object
var a = localStorage.getItem('obj');
var b = JSON.parse(a) // JSON -> array/object
- JSON.stringify() ๋ผ๋ ํจ์์ array/object๋ฅผ ์ง์ด๋ฃ์ผ๋ฉด ๊ทธ ์๋ฆฌ์ JSON์ผ๋ก ๋ณํ๋๊ฑธ ๋จ๊ฒจ์ค๋ค.
- ๋ค์ JSON -> array/object๋ก ๋ณํํ๊ณ ์ถ์ผ๋ฉด JSON.parse() ๋ฅผ ์ฌ์ฉํ๋ฉด ๋๋ค.
๐โ๏ธ ์ต๊ทผ ๋ณธ ์ํ UI ๊ธฐ๋ฅ ๋ง๋ค๊ธฐ
1. ๋๊ฐ Detailํ์ด์ง ์ ์ํ๋ฉด
2. ํ์ฌ ํ์ด์ง์ ๋ณด์ด๋ ์ํid ๊ฐ์ ธ์์
3. localStorage์ watchํญ๋ชฉ์ ์๋ [ ] ์ ์ถ๊ฐ
// Detail.js
useEffect(()=>{
let ๊บผ๋ธ๊ฑฐ = localStorage.getItem('watched')
๊บผ๋ธ๊ฑฐ = JSON.parse(๊บผ๋ธ๊ฑฐ)
๊บผ๋ธ๊ฑฐ.push(์ฐพ์์ํ.id)
//Set์ผ๋ก ๋ฐ๊ฟจ๋ค๊ฐ ๋ค์ array๋ก ๋ง๋ค๊ธฐ -> ์ค๋ณต ์ ๊ฑฐ
๊บผ๋ธ๊ฑฐ = new Set(๊บผ๋ธ๊ฑฐ)
๊บผ๋ธ๊ฑฐ = Array.from(๊บผ๋ธ๊ฑฐ)
localStorage.setItem('watched', JSON.stringify(๊บผ๋ธ๊ฑฐ))
}, [])
โ๏ธ localStorage์ state๋ฅผ ์๋์ ์ฅ๋๊ฒ ๋ง๋ค๊ณ ์ถ์ผ๋ฉด
- redux-persist ์ด๋ฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ค์นํด์ ์ฐ๋ฉด redux store ์์ ์๋ state๋ฅผ ์๋์ผ๋ก localStorage์ ์ ์ฅํด์ค๋ค
- state ๋ณ๊ฒฝ๋ ๋๋ง๋ค ๊ทธ์ ๋ง๊ฒ localStorage ์
๋ฐ์ดํธ๋ ์์์ ํด์ค
- ํ์ง๋ง ์
ํ
๋ฌธ๋ฒ ๋ณต์กํ๊ณ ๊ท์ฐฎ๋ค.
- ๊ทธ๋์ ์์ฆ์ ์ ๊ท ์ฌ์ดํธ๋ค์ Redux ๋์ Jotai, Zustand ๊ฐ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ๋ค.
- ๊ฐ์ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋๋ฐ ์
ํ
๋ ๊ฑฐ์ ํ์์๊ณ ๋ฌธ๋ฒ์ด ํจ์ฌ ๋ ์ฝ๊ณ localStorage ์๋์ ์ฅ๊ธฐ๋ฅ๋ค๋ ์๋ค.
โ๏ธ react-query
! ์
๋ฐ์ดํธ ์ฌํญ
→ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ด๋ฆ์ด react-query์์ @tanstack/react-query๋ก ๋ฐ๊ฟ์ด์
1. ์ค์น์์ ์ด๋ ๊ฒ ์
๋ ฅ
npm install @tanstack/react-query@3
2. import ํด์ ์ฌ์ฉํ ๋ ์ด๋ ๊ฒ ์ ๋ ฅ
import { QueryClient, QueryClientProvider, useQuery } from '@tanstack/react-query'
3. useQuery ์ธ ๋ '์๋ช ' ๋ง๊ณ ['์๋ช ']
useQuery(['์๋ช
'],
๐โ๏ธ ajax ์์ฒญํ๋ค๋ณด๋ฉด ์ด๋ฐ ๊ธฐ๋ฅ๋ค์ด ๊ฐ๋ ํ์ํ๋ค
→ ๋ช์ด๋ง๋ค ์๋์ผ๋ก ๋ฐ์ดํฐ ๋ค์ ๊ฐ์ ธ์ค๊ฒ ํ๋ ค๋ฉด?
→ ์์ฒญ ์คํจ์ ๋ช์ด ๊ฐ๊ฒฉ์ผ๋ก ์ฌ์๋?
→ ๋ค์ ํ์ด์ง ๋ฏธ๋ฆฌ๊ฐ์ ธ์ค๊ธฐ?
→ ajax ์ฑ๊ณต/์คํจ์ ๊ฐ๊ฐ ๋ค๋ฅธ html์ ๋ณด์ฌ์ฃผ๋ ค๋ฉด?
์ด๋ด ๋ ์ฌ์ฉํ๋ ๊ฒ์ด react-query ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ด๋ค.
โ๏ธ react-query ์ค์น & ์
ํ
- ํฐ๋ฏธ๋์์ npm install react-query ํ๊ณ index.js ํ์ผ ์ด์ด์ 1๋ฒ 2๋ฒ 3๋ฒ ํ๋ฉด ๋๋ค.
import { QueryClient, QueryClientProvider } from "react-query" //1๋ฒ
const queryClient = new QueryClient() //2๋ฒ
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<QueryClientProvider client={queryClient}> //3๋ฒ
<Provider store={store}>
<BrowserRouter>
<App />
</BrowserRouter>
</Provider>
</QueryClientProvider>
);
โ๏ธreact-query๋ก ajax ์์ฒญํ๋ ๋ฒ
- ๊ทธ๋ฅ ajax ์์ฒญํด๋ ๋๋๋ฐ react-query๋ฅผ ์จ์ ajax ์์ฒญ ๋ ๋ฆฌ๋ฉด ๋ ํธ๋ฆฌํ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ค.
// ์๋จ์ useQuery import ํด์จ ๋ค
function App(){
let result = useQuery('์๋ช
', ()=>
axios.get('https://codingapple1.github.io/userdata.json')
.then((a)=>{ return a.data })
)
}
์ฅ์ 1. ajax ์์ฒญ ์ฑ๊ณต/์คํจ/๋ก๋ฉ์ค ์ํ๋ฅผ ์ฝ๊ฒ ํ์
ํ ์ ์๋ค.
function App(){
let result = useQuery('์๋ช
', ()=>
axios.get('https://codingapple1.github.io/userdata.json')
.then((a)=>{ return a.data })
)
return (
<div>
{ result.isLoading && '๋ก๋ฉ์ค' }
{ result.error && '์๋ฌ๋จ' }
{ result.data && result.data.name }
</div>
)
}
- result๋ผ๋ ๋ณ์์ ajax ํ์ฌ ์ํ๊ฐ ์์์ ์ ์ฅ๋๋ค.
→ ajax ์์ฒญ์ด ๋ก๋ฉ์ค์ผ ๋ result.isLoading์ด true๊ฐ ๋๋ค.
→ ajax ์์ฒญ์ด ์คํจ์์ result.error๊ฐ true๊ฐ ๋๋ค.
→ ajax ์์ฒญ์ด ์ฑ๊ณต์์ result.data ์์ ๋ฐ์ดํฐ๊ฐ ๋ค์ด์จ๋ค.
- ๊ทธ๋์ "ajax ๋ก๋ฉ์ค์ผ ๋ <A /> ๋ณด์ฌ์ฃผ์ธ์!", "ajax ์ฑ๊ณต์์ <B /> ๋ณด์ฌ์ฃผ์ธ์!" ์ง์ ๊ฐ๋ฐํ ๋ state๋ถํฐ ๋ง๋ค์ด์ผ ํ์๋๋ฐ ์๋ ๊ทธ๋ด ํ์๊ฐ ์๋ค.
์ฅ์ 2. ์์์ ajax ์ฌ์์ฒญํด์ค๋ค.
- ํ์ด์ง ์ฒด๋ฅํ๊ณ ๋์ ์ผ์ ์๊ฐ์ด ๊ฒฝ๊ณผํ๊ฑฐ๋,๋ค๋ฅธ ์ฐฝ์ผ๋ก ๊ฐ๋ค๊ฐ ๋ค์ ํ์ด์ง๋ก ๋์์ค๊ฑฐ๋, ๋ค์ ๋ฉ์ธํ์ด์ง๋ก ๋์๊ฐ๊ฑฐ๋.
- ์ด๋ฐ ์ฌ๋ฌ ๊ฒฝ์ฐ์ ์์์ ajax ์์ฒญ์ ๋ค์ ํด์ค๋ค. (์ฌ์์ฒญ ๋๋ ๋ฒ, ์ฌ์์ฒญ๊ฐ๊ฒฉ ์กฐ์ ํ๋ ๋ฒ๋ ์์)
์ฅ์ 3. ์คํจ์ ์ฌ์๋ ์์์ ํด์ค๋ค.
- ์ ๊น ์ธํฐ๋ท์ด ๋๊ฒผ๊ฑฐ๋ ์๋ฒ๊ฐ ์ฃฝ์๊ฑฐ๋ ๊ทธ๋ฌ๋ฉด ajax ์์ฒญ์ด ์คํจํ๋ค.
- ์คํจํ์ ๋๋ ์๊ฐ ์์์ 4-5ํ ์ ๋ ์ฌ์๋๋ฅผ ํด์ค์ ํธ๋ฆฌํ๋ค.
์ฅ์ 4. ajax๋ก ๊ฐ์ ธ์จ ๊ฒฐ๊ณผ๋ state ๊ณต์ ํ์์๋ค.
- ์ง๊ธ App ์ปดํฌ๋ํธ์์ ์ ์ ์ด๋ฆ ๊ฐ์ ธ์ค๋ ajax ์์ฒญ์ ๋ ๋ฆฌ๊ณ ์๋๋ฐ
- ๊ทธ ์ ์ ์ด๋ฆ ๊ฒฐ๊ณผ๊ฐ Detail ์ปดํฌ๋ํธ์๋ ํ์ํ๋ฉด ์ ์ ์ด๋ฆ์ props๋ก ์ ์กํด์ผํ๋ค.
- ํ์ง๋ง props ์ ์กํ ํ์์์ด Detail ์ปดํฌ๋ํธ์๋ค๊ฐ ์ ์ ์ด๋ฆ ajax ์์ฒญํ๋ ์ฝ๋ ๋๊ฐ์ด ๋ ์ ์ผ๋ฉด ๋๋ค.
- react-query๋ ajax ์์ฒญ์ด 2๊ฐ๋ ์์ผ๋ฉด 1๊ฐ๋ง ๋ ๋ ค์ฃผ๊ณ
- ์บ์ฑ ๊ธฐ๋ฅ์ด ์๊ธฐ ๋๋ฌธ์ ์ด๋ฏธ ๊ฐ์ ajax ์์ฒญ์ ํ ์ ์ด ์์ผ๋ฉด ๊ทธ๊ฑธ ์ฐ์ ๊ฐ์ ธ์์ ์ฌ์ฉํ๋ค.
๐โ๏ธ react-query๊ฐ ์ฃผ์ฅํ๋ ์ฅ์ ์
- server-state (DB ๋ฐ์ดํฐ)๋ฅผ ํ๋ก ํธ์๋์์ ์ค์๊ฐ ๋๊ธฐํํด์ฃผ๋๊ฑธ ๋์์ค๋ค๊ณ ํ๋ค.
- ๊ทผ๋ฐ ajax ์์ฒญ์ ๋ช์ด๋ง๋ค ๊ณ์ ๋ ๋ ค์ ๊ฐ์ ธ์ค๋ ๋ฐฉ์์ด๋ผ http1์ ์ฐ๋ ์๋ฒ๋ ๋ธ๋ผ์ฐ์ ๋ผ๋ฉด ์ข ๋นํจ์จ์ ์ผ ์๋ ์๋ค.
- ์ค์๊ฐ์ผ๋ก ์๋ฒ์์ ๋ฐ์ดํฐ๋ฅผ ์์ฃผ ๋ณด๋ด๋ ค๋ฉด ์น์์ผ์ด๋ server-sent events ๊ฐ์ ๊ฐ๋ฒผ์ด ๋ฐฉ์๋ ์๋ค.
- ๊ทธ๋์ react-query๋ ajax ๊ด๋ จ ๊ธฐ๋ฅ๊ฐ๋ฐ์ ํธํ๊ฒ ํ ์ ์๋๋ฐ์ ์์๊ฐ ์๋ค.
๐โ๏ธRTK Query ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ์๋ค
- ajax ์์ฒญ ํ Resux state ๋ณ๊ฒฝํ๊ณ ์ถ์ผ๋ฉด Slice ์์์ ๊ด๋ฆฌ๊ฐ๋ฅํ๊ฒ ๋์์ค๋ค.
- ๊ทธ๋ฆฌ๊ณ ajax ์์ฒญํ๋ ์ฝ๋๊ฐ 100๋ง๊ฐ ์์ผ๋ฉด ๊ทธ๊ฑธ ํธ๋ฆฌํ๊ฒ ๊ด๋ฆฌํ ์ ์๊ฒ ๋์์ค๋ค.(๋จ ์ฝ๋๊ฐ ์กฐ๊ธ ๋๋ฌ์์ง ์๋..!)
๋ณธ ํฌ์คํ ์ << React ๋ฆฌ์กํธ ๊ธฐ์ด๋ถํฐ ์ผํ๋ชฐ ํ๋ก์ ํธ๊น์ง! >> ๊ฐ์๋ฅผ ์ฐธ๊ณ ํฉ๋๋ค.