โœ๐Ÿป [Code Camp_TIL] 34์ผ์ฐจ: Optimistic-UI

code_Jยท2023๋…„ 5์›” 1์ผ
0

TIL

๋ชฉ๋ก ๋ณด๊ธฐ
41/41
post-thumbnail

Optimistic-UI(์˜ตํ‹ฐ๋ฏธ์Šคํ‹ฑ UI)


์šฐ๋ฆฌ๊ฐ€ ์–ด๋–ค ๊ฒŒ์‹œ๊ธ€์— ์ข‹์•„์š”๋ฅผ ๋ˆ„๋ฅด๋ฉด ํ™˜๊ฒฝ์— ๋”ฐ๋ผ ์ข‹์•„์š” ์ˆ˜๊ฐ€ ์˜ฌ๋ผ๊ฐ€๋Š” ์†๋„๊ฐ€ ๋‹ค๋ฅด๋‹ค. ์™œ ๊ทธ๋Ÿด๊นŒ?

์ข‹์•„์š”๋ฅผ ๋ˆŒ๋ €์„ ๋•Œ ์ฒ˜๋ฆฌ ๊ณผ์ •
1. ๋ฐฑ์—”๋“œ์— api ์š”์ฒญ, ๋ฐฑ์—”๋“œ๋Š” DB์— ์š”์ฒญ
2. DB๋Š” ์ข‹์•„์š” ์ˆ˜๋ฅผ ์˜ฌ๋ ค๋‘๊ณ  ์˜ฌ๋ฆฐ ์ข‹์•„์š” ์ˆ˜ ์‘๋‹ต
3. ๋ฐฑ์—”๋“œ๋Š” ํ•ด๋‹น ์‘๋‹ต์„ ๋‹ค์‹œ ๋ธŒ๋ผ์šฐ์ €์— ์‘๋‹ต

ํ™˜๊ฒฝ์— ๋”ฐ๋ผ ์œ„ ๊ณผ์ •์„ ์ˆ˜ํ–‰ํ•˜๋Š”๋ฐ ์‹œ๊ฐ„์ด ์˜ค๋ž˜ ๊ฑธ๋ฆด ์ˆ˜๋„ ์žˆ๋‹ค. ์ด๋Ÿด ๋•Œ Optimistic UI๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.


Optimistic UI๋Š” ์š”์ฒญ์ด ์„œ๋ฒ„์— ๋„๋‹ฌํ•˜๊ธฐ๋„ ์ „์— ํ™”๋ฉด์˜ ๊ฐ’์„ ๋ฐ”๊พธ๋Š” ๊ฒƒ์ด๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์š”์ฒญ์ด ์„ฑ๊ณตํ•˜๊ณ  ๋‚˜๋ฉด ์‘๋‹ต์œผ๋กœ ๋Œ์•„์˜จ ๊ฐ’์„ ๋‹ค์‹œ ํ™”๋ฉด์— ์—…๋ฐ์ดํŠธํ•œ๋‹ค. ์ด ๊ณผ์ •์—์„œ ์œ ์ €๋Š” ๋ณ€ํ™”๋ฅผ ๋ˆˆ์น˜์ฑ„์ง€ ๋ชปํ•œ๋‹ค.

๋งŒ์•ฝ ์ค‘๊ฐ„์— ์š”์ฒญ์ด ์‹คํŒจํ•œ๋‹ค๋ฉด ์ด์ „์˜ ๊ฐ’์„ ์‘๋‹ต์œผ๋กœ ๋ณด๋‚ด์ฃผ๊ณ  ์ด์ „์˜ ๊ฐ’์„ ํ™”๋ฉด์— ์—…๋ฐ์ดํŠธ ํ•ด์ค€๋‹ค(๋กค๋ฐฑ).


๋”ฐ๋ผ์„œ Optimistic-UI๋Š” ์„ฑ๊ณต์„ 99% ํ™•์‹ ํ•˜๋Š” api์— ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค. ๋กค๋ฐฑ(์‹คํŒจ)๋˜์–ด๋„ ํฐ ์ด์Šˆ๊ฐ€ ์—†๋Š” ๊ฒƒ์—๋งŒ ์‚ฌ์šฉํ•˜์ž!

์˜ˆ๋ฅผ ๋“ค์–ด, ๊ฒฐ์ œ ํ›„ ์ž”์—ฌ ๊ธˆ์•ก๊ณผ ๊ฐ™์€ ์ค‘์š”ํ•œ api๋Š” ์†๋„์— ์ƒ๊ด€์—†์ด ์ œ๋Œ€๋กœ ์ ˆ์ฐจ๋ฅผ ๊ฑฐ์ณ์„œ ๋™์ž‘ํ•ด์•ผ ํ•˜์ง€๋งŒ, ์ข‹์•„์š”์™€ ๊ฐ™์€ api๋Š” ์†์ž„์ˆ˜๋ฅผ ์จ์„œ ๋น ๋ฅด๊ฒŒ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.


์•„๋ž˜ ๊ทธ๋ฆผ์€ ์ข‹์•„์š”๋ฅผ ๋ˆŒ๋ €์„ ๋•Œ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ ๊ณผ์ •์„ ๋‚˜ํƒ€๋‚ธ ๊ฒƒ์ด๋‹ค. (์œ„: ๊ธฐ์กด ๋ฐฉ์‹, ์•„๋ž˜: Optimistic-UI)


์ข‹์•„์š”๋ฅผ ์˜ฌ๋ฆฌ๋Š” api์ธ, likeBoard ์š”์ฒญ์— Optimistic-UI๋ฅผ ์‚ฌ์šฉํ•ด๋ดค๋‹ค.

// import ๋ถ€๋ถ„ ์ƒ๋žต

// ๊ฒŒ์‹œ๊ธ€ ์กฐํšŒ api์—์„œ ์ข‹์•„์š” ๊ฐฏ์ˆ˜๋งŒ ๋ฝ‘์•„ ์˜ค๊ธฐ
const FETCH_BOARD = gql`
	query fetchBoard($boardId: ID!){
		fetchBoard(boardId: $boardId){
			_id
			likeCount
		}
	}
`

//์ข‹์•„์š” ์นด์šดํŠธ ์˜ฌ๋ฆฌ๋Š” api
const LIKE_BOARD = gql`
	mutation likeBoard($boardId:ID!){
		likeBoard(boardId:$boardId)
	}
`

export default function(){
	const [likeBoard] = useMutation<Pick<IMutation,"likeBoard">,IMutationLikeBoardArgs>(LIKE_BOARD)
	const { data } = useQuery(FETCH_BOARD,
		{variables :{boardId : "๊ฒŒ์‹œ๊ธ€ ์•„์ด๋”” ๋„ฃ์–ด์ฃผ์„ธ์š”!"} })
	
	const onClickLike = ()=>{
		//likeBoard ๋ฎคํ…Œ์ด์…˜ ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.
		void likeBoard({
			variables :{
				boardId : "๊ฒŒ์‹œ๊ธ€ ์•„์ด๋”” ๋„ฃ์–ด์ฃผ์„ธ์š”!"
			},

// (๊ธฐ์กด ๋ฐฉ์‹) ์‘๋‹ต์„ ๋ฐ›๊ณ ๋‚œ ํ›„ ๋ฐ›์•„์˜จ ์‘๋‹ต์„ ๋‹ค์‹œ fetch ํ•ด์คŒ -> ๋Š๋ฆฌ๊ณ  ํšจ์œจ์ ์ด์ง€ ๋ชปํ•จ(๋ฐฑ์—”๋“œ์— ์š”์ฒญ์„ ํ•œ๋ฒˆ๋” ํ•ด์•ผ ํ•˜๊ณ  ๋ฐ›์•„์˜ฌ ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ ค์•ผ ํ•จ)
		//refetchQueries: [
		//	{
		//		query: FETCH_BOARD,
		//		variables : {	boardId : "//๊ฒŒ์‹œ๊ธ€ ์•„์ด๋”” ๋„ฃ์–ด์ฃผ์„ธ์š”!" }
		//	}
		// ]

// ์˜ตํ‹ฐ๋ฏธ์Šคํ‹ฑ UI -> ์บ์‹œ๋ฅผ ๋ฐ”๊พธ๊ณ  ์บ์‹œ๊ฐ’์„ ๋ฐ›์•„์˜ค๋Š”๊ฑธ ๊ธฐ๋‹ค๋ฆฌ์ง€ ์•Š๊ณ  ๋ฐ”๋กœ ๋ฐ”๊ฟ”์คŒ
		optimisticResponse: {
			likeBoard : (data?.fetchBoard.likeCount || 0)+1
                         },
// apollo ์บ์‹œ ์ง์ ‘ ์ˆ˜์ •(๋ฐฑ์—”๋“œ ์บ์‹œ X) -> ๋Š๋ฆฌ์ง€๋งŒ ํšจ์œจ์ (๋ฐฑ์—”๋“œ์— ์š”์ฒญ์€ ์•ˆํ•˜์ง€๋งŒ, ๋ฐ›์•„์˜ฌ ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ ค์ค˜์•ผ ํ•จ)
			update(cache,{data}){
// ์ด์ „ ์‹œ๊ฐ„์—๋Š” modify๋ฅผ ์‚ฌ์šฉํ–ˆ์ง€๋งŒ, ์˜ค๋Š˜์€ writeQuery๋ฅผ ์‚ฌ์šฉํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.
				cache.writeQuery({
					query : FETCH_BOARD,
					variables : {boardId:'๊ฒŒ์‹œ๊ธ€ ์•„์ด๋”” ๋„ฃ์–ด์ฃผ์„ธ์š”!'}
					//์–ด๋–ป๊ฒŒ ์ˆ˜์ •ํ•  ๊ฒƒ์ธ์ง€๋Š” ์•„๋ž˜์— ์ ์–ด์คŒ
					data: {
						// ๊ธฐ์กด๊ฐ’๊ณผ ๋˜‘๊ฐ™์ด ๋ฐ›์•„์™€์•ผ ํ•จ
						fetchBoard: {
							_id : '๊ฒŒ์‹œ๊ธ€ ์•„์ด๋”” ๋„ฃ์–ด์ฃผ์„ธ์š”!',
							__typename : "Board"
							likeCount: data?.likeBoard
						}
					}
				})
			}
		})
	}

	return(
		<div>
				<h1>์˜ตํ‹ฐ๋ฏธ์Šคํ‹ฑ UI</h1>
				<div>ํ˜„์žฌ์นด์šดํŠธ(์ข‹์•„์š”):{data.fetchBoard.likeCount}</div>
				<button onClick={onClickOptimisticUI}>์ข‹์•„์š” ์˜ฌ๋ฆฌ๊ธฐ!!</button>
		</div>
	)
} 

optimistic-ui๋ฅผ ์ ์šฉํ•˜๋ฉด ์ปดํ“จํ„ฐ ํ™˜๊ฒฝ์— ์ƒ๊ด€์—†์ด ์œ ์ € ๋ชจ๋‘๊ฐ€ ๋น ๋ฅธ ์„œ๋น„์Šค๋ฅผ ์ด์šฉํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ผ ์ˆ˜ ์žˆ๋‹ค. ์ƒํ™ฉ์— ๋”ฐ๋ผ ๋ฐ์ดํ„ฐ๊ฐ€ ์ค‘์š”ํ•˜์ง€ ์•Š๊ณ  ์‹คํŒจ ํ™•๋ฅ ์ด ๊ทนํžˆ ๋‚ฎ์„ ๊ฒฝ์šฐ ์‚ฌ์šฉํ•ด์ฃผ๋ฉด ์ข‹๋‹ค!



์ •๋ฆฌ) ์„ฑ๋Šฅ ์ตœ์ ํ™”๋ฅผ ์œ„ํ•œ 8๊ฐ€์ง€ ์ „๋žต!

์œ„์˜ 8๊ฐ€์ง€ ์ „๋žต์€ ๋ฐ˜๋“œ์‹œ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค. ์ƒํ™ฉ๊ณผ ํ™˜๊ฒฝ์— ๋งž๊ฒŒ ์žฅ๋‹จ์ ์„ ์ž˜ ๊ณ ๋ คํ•ด์„œ ์‚ฌ์šฉํ•˜๋ฉด, ์‚ฌ์šฉ์ž์˜ ๋งŒ์กฑ๋„๋ฅผ ๋†’์ด๋Š” ์ „๋žต์ด ๋  ์ˆ˜ ์žˆ๋‹ค.




profile
Web FE ๊ฐœ๋ฐœ์ž ์ทจ์ค€์ƒ

0๊ฐœ์˜ ๋Œ“๊ธ€