๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

๐Ÿ’ปWEB FrontEnd/ํ”„๋ ˆ์ž„์›Œํฌ React

(20)
PWA(Progressive Web App) PWA(Progressive Web App) ์›น์‚ฌ์ดํŠธ๋ฅผ ์•ˆ๋“œ๋กœ์ด๋“œ/iOS ๋ชจ๋ฐ”์ผ ์•ฑ์ฒ˜๋Ÿผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋งŒ๋“œ๋Š” ์ผ์ข…์˜ ์›น๊ฐœ๋ฐœ ๊ธฐ์ˆ  (์žฅ์ ) 1. ์Šค๋งˆํŠธํฐ, ํƒœ๋ธ”๋ฆฟ ๋ฐ”ํƒ•ํ™”๋ฉด์— ์—ฌ๋Ÿฌ๋ถ„ ์›น์‚ฌ์ดํŠธ๋ฅผ ์„ค์น˜ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. (์ €๊ฑฐ ์„ค์น˜๋œ ์•ฑ ๋ˆ„๋ฅด๋ฉด ์ƒ๋‹จ URL๋ฐ”๊ฐ€ ์ œ๊ฑฐ๋œ ํฌ๋กฌ ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ๋œน๋‹ˆ๋‹ค. ์ผ๋ฐ˜ ์‚ฌ์šฉ์ž๋Š” ์•ฑ์ด๋ž‘ ๊ตฌ๋ถ„์„ ๋ชปํ•จ) 2. ์˜คํ”„๋ผ์ธ์—์„œ๋„ ๋™์ž‘ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. service-worker.js ๋ผ๋Š” ํŒŒ์ผ๊ณผ ๋ธŒ๋ผ์šฐ์ €์˜ Cache storage ๋•๋ถ„์— ๊ทธ๋ ‡์Šต๋‹ˆ๋‹ค. ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋กœ ๊ฒŒ์ž„๋งŒ๋“ค ๋•Œ ์œ ์šฉํ•˜๊ฒ ๋„ค์š”. 3. ์„ค์น˜ ์œ ๋„ ๋น„์šฉ์ด ๋งค์šฐ ์ ์Šต๋‹ˆ๋‹ค. ์•ฑ์„ค์น˜๋ฅผ ์œ ๋„ํ•˜๋Š” ๋งˆ์ผ€ํŒ… ๋น„์šฉ์ด ์ ๊ฒŒ๋“ค์–ด ์ข‹๋‹ค๋Š” ๊ฒ๋‹ˆ๋‹ค. ๊ตฌ๊ธ€ํ”Œ๋ ˆ์ด ์Šคํ† ์–ด ๋ฐฉ๋ฌธํ•ด์„œ ์•ฑ ์„ค์น˜ํ•˜๊ณ  ๋‹ค์šด๋ฐ›๊ฒŒ ํ•˜๋Š”๊ฑด ํ•ญ์ƒ ๋งค์šฐ ๋†’์€ ๋งˆ์ผ€ํŒ…๋น„์šฉ์ด ๋“ญ๋‹ˆ๋‹ค. ๊ทผ๋ฐ PWA๋ผ๋ฉด ์›น์‚ฌ์ด..
์„ฑ๋Šฅ๊ฐœ์„ (3) - batching, useTransition, useDeferredValue batching - state๋ณ€๊ฒฝํ•จ์ˆ˜๋ฅผ ์—ฐ๋‹ฌ์•„์„œ 3๊ฐœ ์‚ฌ์šฉํ•˜๋ฉด ์žฌ๋ Œ๋”๋ง๋„ ์›๋ž˜ 3๋ฒˆ ๋˜์–ด์•ผํ•˜์ง€๋งŒ ๋ฆฌ์•กํŠธ๋Š” ๋˜‘๋˜‘ํ•˜๊ฒŒ๋„ ์žฌ๋ Œ๋”๋ง์„ ๋งˆ์ง€๋ง‰์— 1ํšŒ๋งŒ ์ฒ˜๋ฆฌํ•ด์ค€๋‹ค. ์ด๋Ÿฐ ์žฌ๋ Œ๋”๋ง ๋ฐฉ์ง€๊ธฐ๋Šฅ์„ batching์ด๋ผ๊ณ  ํ•œ๋‹ค. - ๊ทผ๋ฐ ๋ฌธ์ œ๋Š” ajax์š”์ฒญ, setTimeout์•ˆ์— state๋ณ€๊ฒฝํ•จ์ˆ˜๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ batching์ด ์ผ์–ด๋‚˜์ง€ ์•Š๋Š”๋‹ค. ๋ฆฌ์•กํŠธ 17๋ฒ„์ „๊นŒ์ง„ ๊ทธ๋Ÿฐ ์‹์œผ๋กœ ์ผ๊ด€์ ์ด์ง€ ์•Š๊ฒŒ ๋™์ž‘ํ–ˆ๋Š”๋ฐ18๋ฒ„์ „ ์ดํ›„ ๋ถ€ํ„ฐ๋Š” ์–ด๋”” ์žˆ๋“  ๊ฐ„์— ์žฌ๋ Œ๋”๋ง์€ ๋งˆ์ง€๋ง‰์— 1๋ฒˆ๋งŒ ๋œ๋‹ค. - batching ๋˜๋Š”๊ฒŒ ์‹ซ๊ณ  state๋ณ€๊ฒฝํ•จ์ˆ˜ ์‹คํ–‰๋งˆ๋‹ค ์žฌ๋ Œ๋”๋ง์‹œํ‚ค๊ณ  ์‹ถ์œผ๋ฉด flushSync๋ผ๋Š” ํ•จ์ˆ˜๋ฅผ ์“ฐ๋ฉด ๋œ๋‹ค. setCount(1) setName(2) setValue(3) //์—ฌ๊ธฐ์„œ 1๋ฒˆ๋งŒ ์žฌ๋ Œ๋”๋ง๋จ useTransition useTransi..
์„ฑ๋Šฅ๊ฐœ์„ (2) - ์žฌ๋ Œ๋”๋ง ๋ง‰๋Š” ๋ฒ• ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์žฌ๋ Œ๋”๋ง๋˜๋ฉด ๊ฑฐ๊ธฐ ์•ˆ์— ์žˆ๋Š” ์ž์‹์ปดํฌ๋„ŒํŠธ๋Š” ํ•ญ์ƒ ํ•จ๊ป˜ ์žฌ๋ Œ๋”๋ง๋œ๋‹ค. ์ด๋Ÿฐ ์žฌ๋ Œ๋”๋ง์„ ๋ง‰๊ณ  ์‹ถ์„ ๋• ์ž์‹์„ memo๋กœ ๊ฐ์‹ธ๋†“์œผ๋ฉด ๋œ๋‹ค. memo()๋กœ ์ปดํฌ๋„ŒํŠธ ๋ถˆํ•„์š”ํ•œ ์žฌ๋ Œ๋”๋ง ๋ง‰๊ธฐ step 1) memo๋ฅผ 'react' ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ๋ถ€ํ„ฐ import ํ•ด์™€์„œ step 2) ์›ํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ ์ •์˜๋ถ€๋ถ„์„ ๊ฐ์‹ผ๋‹ค. ๊ทผ๋ฐ ์ปดํฌ๋„ŒํŠธ๋ฅผ let ์ปดํฌ๋„ŒํŠธ๋ช… = function( ){ } ์ด๋Ÿฐ ์‹์œผ๋กœ ๋งŒ๋“ค์–ด์•ผ ๊ฐ์Œ€ ์ˆ˜ ์žˆ๋‹ค. import {memo, useState} from 'react' let Child = memo( function(){ console.log('์žฌ๋ Œ๋”๋ง๋จ') return ์ž์‹์ž„ }) function Cart(){ let [count, setCount] = useState(0) return ( ..
์„ฑ๋Šฅ๊ฐœ์„ (1) - lazy import lazy import - ๋ฆฌ์•กํŠธ ์‚ฌ์ดํŠธ๋“ค์€ ์ฒซ ํŽ˜์ด์ง€ ๋กœ๋”ฉ์†๋„๊ฐ€ ๋งค์šฐ ๋Š๋ฆด ์ˆ˜ ์žˆ๋Š”๋ฐ ๊ทธ๊ฒŒ ์‹ซ๋‹ค๋ฉด js ํŒŒ์ผ์„ ์ž˜๊ฒŒ ์ชผ๊ฐœ๋ฉด ๋œ๋‹ค. - ์ชผ๊ฐœ๋Š” ๋ฐฉ๋ฒ•์€ import ๋ฌธ๋ฒ•์„ ์•ฝ๊ฐ„ ๊ณ ์น˜๋ฉด ๋˜๋Š”๋ฐ ์ง€๊ธˆ ํŽ˜์ด์ง€์—์„œ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ์žˆ๋Š” ์ปดํฌ๋„ŒํŠธ๋“ค์€ lazy import ํ•ด๋†“์œผ๋ฉด ์ข‹๋‹ค. - ๋‹จ์  : lazy๋ฌธ๋ฒ•์œผ๋กœ importํ•œ ์ปดํฌ๋„ŒํŠธ๋“ค์„ ๋กœ๋“œํ•  ๋•Œ๋Š” ๋กœ๋”ฉ์‹œ๊ฐ„์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค. 1. lazy() (App.js) import Detail from './routes/Detail.js' import Cart from './routes/Cart.js' โ†“โ†“โ†“ (App.js) import {lazy, Suspense, useEffect, useState} from 'react' const Detail = lazy( () =..
react-query : ์‹ค์‹œ๊ฐ„ ๋ฐ์ดํ„ฐ๊ฐ€ ์ค‘์š”ํ•  ๋•Œ? ajax ์š”์ฒญํ•˜๋‹ค๋ณด๋ฉด ์ด๋Ÿฐ ๊ธฐ๋Šฅ๋“ค์ด ๊ฐ€๋” ํ•„์š”ํ•ด์ง„๋‹ค. - ๋ช‡์ดˆ๋งˆ๋‹ค ์ž๋™์œผ๋กœ ๋ฐ์ดํ„ฐ ๋‹ค์‹œ ๊ฐ€์ ธ์˜ค๊ฒŒ ํ•˜๋ ค๋ฉด? - ์š”์ฒญ์‹คํŒจ์‹œ ๋ช‡์ดˆ ๊ฐ„๊ฒฉ์œผ๋กœ ์žฌ์‹œ๋„? - ๋‹ค์Œ ํŽ˜์ด์ง€ ๋ฏธ๋ฆฌ๊ฐ€์ ธ์˜ค๊ธฐ? - ajax ์„ฑ๊ณต/์‹คํŒจ์‹œ ๊ฐ๊ฐ ๋‹ค๋ฅธ html์„ ๋ณด์—ฌ์ฃผ๋ ค๋ฉด? 1. react-query ์„ค์น˜ & ์…‹ํŒ… (terminal) npm install react-query (index.js) import { QueryClient, QueryClientProvider } from "react-query" //1๋ฒˆ const queryClient = new QueryClient() //2๋ฒˆ const root = ReactDOM.createRoot(document.getElementById('root')); root.render( //3๋ฒˆ ); ..
localStorage 1. localStorage ๋ฌธ๋ฒ• ์ถ”๊ฐ€, ์ฝ๊ธฐ, ์‚ญ์ œ ๋ฌธ๋ฒ• localStorage.setItem('๋ฐ์ดํ„ฐ์ด๋ฆ„', '๋ฐ์ดํ„ฐ'); localStorage.getItem('๋ฐ์ดํ„ฐ์ด๋ฆ„'); localStorage.removeItem('๋ฐ์ดํ„ฐ์ด๋ฆ„') 2. localStorage์— array/object ์ž๋ฃŒ๋ฅผ ์ €์žฅํ•˜๋ ค๋ฉด ๋ฌธ์ž๋งŒ ์ €์žฅํ•  ์ˆ˜ ์žˆ๋Š” ๊ณต๊ฐ„์ด๋ผ array/object๋ฅผ ๋ฐ”๋กœ ์ €์žฅํ•  ์ˆ˜๋Š” ์—†๋‹ค. ํŽธ๋ฒ•์œผ๋กœ array/object -> JSON ์ด๋ ‡๊ฒŒ ๋ณ€ํ™˜ํ•ด์„œ ์ €์žฅํ•˜๋ฉด ๋œ๋‹ค. (JSON์€ ๋ฌธ์ž์ทจ๊ธ‰) JSON.stringify() ๋ผ๋Š” ํ•จ์ˆ˜์— array/object๋ฅผ ์ง‘์–ด๋„ฃ์œผ๋ฉด ๊ทธ ์ž๋ฆฌ์— JSON์œผ๋กœ ๋ณ€ํ™˜๋œ๊ฑธ ๋‚จ๊ฒจ์ค€๋‹ค. localStorage.setItem('obj', JSON.stringify({name:'ki..
Redux (2) - state ๋ณ€๊ฒฝ 1. store์˜ state ๋ณ€๊ฒฝํ•˜๋Š” ๋ฒ• step 1) store.js ์•ˆ์— state ์ˆ˜์ •ํ•ด์ฃผ๋Š” ํ•จ์ˆ˜ ์ƒ์„ฑ - slice ์•ˆ์— reducers : { } ์—ด๊ณ  ๊ฑฐ๊ธฐ ์•ˆ์— ํ•จ์ˆ˜ ๋งŒ๋“ค๋ฉด ๋œ๋‹ค. (ํ•จ์ˆ˜ ์ž‘๋ช…์€ ์ž์œ ๋กญ๊ฒŒ) - ํŒŒ๋ผ๋ฏธํ„ฐ ํ•˜๋‚˜ ์ž‘๋ช…ํ•˜๋ฉด ๊ทธ๊ฑด ๊ธฐ์กด state๊ฐ€ ๋œ๋‹ค. - return ์šฐ์ธก์— ์ƒˆ๋กœ์šด state ์ž…๋ ฅํ•˜๋ฉด ๊ทธ๊ฑธ๋กœ ๊ธฐ์กด state๋ฅผ ๋ณ€๊ฒฝํ•ด์ค€๋‹ค. let user = createSlice({ name : 'user', initialState : 'kim', reducers : { //state ์ˆ˜์ •ํ•ด์ฃผ๋Š” ํ•จ์ˆ˜ changeName(state){ return 'john ' + state }, ์ˆ˜์ •ํ•จ์ˆ˜2(state){ return ... }, } }) step 2) ์ƒ์„ฑํ•œ ์ˆ˜์ •ํ•จ์ˆ˜(changeNam..
Redux (1) : props ์—†์ด state ๊ณต์œ  ๊ฐ€๋Šฅ Redux Redux๋Š” props ์—†์ด state๋ฅผ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋„์™€์ฃผ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ด๋‹ค. 1. Redux ์„ค์น˜ npm install @reduxjs/toolkit react-redux โ€ป redux toolkit : redux์˜ ๊ฐœ์„ ๋ฒ„์ „ (๋ฌธ๋ฒ•์ด ์ข€ ๋” ์‰ฌ์›Œ์ง) ๊ทผ๋ฐ ์„ค์น˜ํ•˜๊ธฐ ์ „์— package.json ํŒŒ์ผ์„ ์—ด์–ด์„œ "react", "react-dom" ํ•ญ๋ชฉ์˜ ๋ฒ„์ „์„ ํ™•์ธํ•œ๋‹ค. ์ด๊ฑฐ ๋‘๊ฐœ๊ฐ€ 18.1.x ์ด์ƒ์ด๋ฉด ์‚ฌ์šฉ๊ฐ€๋Šฅํ•˜๋‹ค. โ–ฒ ๊ทธ๊ฒŒ ์•„๋‹ˆ๋ฉด ์ง์ ‘ ๋‘๊ฐœ๋ฅผ 18.1.0 ์ด๋ ‡๊ฒŒ ์ˆ˜์ •ํ•œ ๋‹ค์Œ ํŒŒ์ผ์ €์žฅํ•˜๊ณ  ํ„ฐ๋ฏธ๋„์—์„œ npm install ๋ˆ„๋ฅด๋ฉด ๋œ๋‹ค. 2. Redux ์…‹ํŒ… โ‘  ์•„๋ฌด๊ณณ(์˜ˆ๋ฅผ ๋“ค๋ฉด, src ํด๋” ์•ˆ)์ด๋‚˜ state๋“ค์„ ๋ณด๊ด€ํ•˜๋Š” ํŒŒ์ผ์ธ store.js ํŒŒ์ผ์„ ๋งŒ๋“ค์–ด์„œ ์•„๋ž˜ ์ฝ”๋“œ๋ฅผ ๋ณต๋ถ™ํ•ด์ค€๋‹ค. (s..
Ajax๋กœ ์„œ๋ฒ„์™€ ํ†ต์‹  Ajax๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ๋‹ค์Œ ์„ธ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์ด ์žˆ๋‹ค. XMLHttpRequest fetch() axios 1. axios ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์‚ฌ์šฉ 1) axios ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์„ค์น˜ npm install axios 2) App.js์— axios ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ import import axios from 'axios' 3) AJAX GET ์š”์ฒญํ•˜๊ธฐ { axios.get('https://codingapple1.github.io/shop/data2.json').then((๊ฒฐ๊ณผ)=>{ console.log(๊ฒฐ๊ณผ.data) }) .catch(()=>{ console.log('์‹คํŒจํ•จ') }) //๋™์‹œ์— ajax ์š”์ฒญ ์—ฌ๋Ÿฌ๊ฐœํ•˜๋ ค๋ฉด Promise.all( [axios.get('URL1'), axios.get('URL2')] ) }}>๋ฒ„ํŠผ..
์ปดํฌ๋„ŒํŠธ์˜ Lifecycle ์ปดํฌ๋„ŒํŠธ์˜ Lifecycle ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์‹คํ–‰๋˜๊ณ  ์ข…๋ฃŒ๋˜๋Š” ๊ณผ์ •์„ ํŠน์ • ์‹œ์ ๋ณ„๋กœ ๋‚˜๋ˆ„์–ด ๋‘” ๊ฒƒ ์ปดํฌ๋„ŒํŠธ๋Š” 1. ์ƒ์„ฑ์ด ๋  ์ˆ˜๋„ ์žˆ๊ณ  (mount) 2. ์žฌ๋ Œ๋”๋ง์ด ๋  ์ˆ˜๋„ ์žˆ๊ณ  (update) 3. ์‚ญ์ œ๊ฐ€ ๋  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. (unmount) Lifecycle Hook ํ•จ์ˆ˜ํ˜• ์ปดํฌ๋„ŒํŠธ์—์„œ๋„ ํด๋ž˜์Šคํ˜• ์ปดํฌ๋„ŒํŠธ์˜ ๊ธฐ๋Šฅ(React State, Lifecycle Method)์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ๋งŒ๋“ค์–ด์ฃผ๋Š” ๊ธฐ๋Šฅ์ด๋‹ค. Hook์€ ๋ชจ๋‘ use๋กœ ์‹œ์ž‘ํ•œ๋‹ค๋Š” ํŠน์ง•์ด ์žˆ๋‹ค. ์—ฌ๋Ÿฌ ์ปดํฌ๋„ŒํŠธ์—์„œ ์žฌ์‚ฌ์šฉ ๋  ์ˆ˜ ์žˆ๋Š” ๋กœ์ง์ด๋ผ๋ฉด ์‚ฌ์šฉ์ž๊ฐ€ ์ •์˜ํ•ด์„œ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค. => custom hooks 1) ํด๋ž˜์Šคํ˜• ์ปดํฌ๋„ŒํŠธ์˜ Lifecycle Hook class Detail2 extends React.Component { component..