23.05.03 TIL๐Ÿ”ฅ

์ƒค์ด๋‹ˆยท2023๋…„ 5์›” 3์ผ
0

learned.log

๋ชฉ๋ก ๋ณด๊ธฐ
43/46

์˜ค๋Š˜์€ ๋ฌด์—‡์„ ํ–ˆ๋‚˜์š”?

ํ† ๋‹ˆ์™€ ๊ฑฐ์˜ 7์‹œ๊ฐ„ ๋„˜๊ฒŒ ToDoList ํŽ˜์–ดํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ์ง„ํ–‰ํ–ˆ๋‹ค.

์บ˜๋ฆฐ๋”์™€ ํˆฌ๋‘ ๋ฆฌ์ŠคํŠธ ์ถ”๊ฐ€ ๊ธฐ๋Šฅ๊นŒ์ง€ ๊ตฌํ˜„ ์™„๋ฃŒ! ์šฐ์„ ์€ ํŽ˜์–ดํ”„๋กœ๊ทธ๋ž˜๋ฐ์œผ๋กœ ๊ธฐ๋Šฅ ๊ตฌํ˜„์„ ํ•˜๊ณ , css style ์ ์šฉ์€ figma๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๊ฐ์ž ํŒŒํŠธ๋ฅผ ๋‚˜๋ˆ  ๊ธˆ์š”์ผ์— ์ง„ํ–‰ํ•˜๊ธฐ๋กœ ๊ฒฐ์ •ํ–ˆ๋‹ค.

์˜ค๋Š˜์˜ ๋‚˜๋Š” ๋ฌด์—‡์„ ์ƒˆ๋กญ๊ฒŒ ๋ฐฐ์› ๋‚˜์š”?

[1] Batching์ด๋ž€?

React๊ฐ€ย ์„ฑ๋Šฅ์„ ํ–ฅ์ƒ์‹œํ‚ค๊ธฐ ์œ„ํ•ด ์—ฌ๋Ÿฌ ๊ฐœ์˜ state ์—…๋ฐ์ดํŠธ๋ฅผ ํ•˜๋‚˜์˜ ๋ฆฌ๋ Œ๋”๋ง์œผ๋กœ ๋ฌถ๋Š” ๊ฒƒ

์˜ˆ๋ฅผ ๋“ค์–ด, ํ•˜๋‚˜์˜ ํด๋ฆญ ์ด๋ฒคํŠธ ์•ˆ์— ๋‘ ๊ฐœ์˜ state ์—…๋ฐ์ดํŠธ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค๋ฉด, React๋Š” ์–ธ์ œ๋‚˜ ์ด ์ž‘์—…์„ batch ์—…๋ฐ์ดํŠธํ•˜์—ฌ ํ•˜๋‚˜์˜ ๋ฆฌ๋ Œ๋”๋ง์œผ๋กœ ๋งŒ๋“ญ๋‹ˆ๋‹ค.ย ์ด ๊ณผ์ •์€ ๋ถˆํ•„์š”ํ•œ ๋ฆฌ๋ Œ๋”๋ง์„ ์ค„์ด๊ณ , ์ปดํฌ๋„ŒํŠธ๊ฐ€ โ€œ๋ฐ˜๋งŒ ์™„๋ฃŒ๋œโ€ state๋ฅผ ๋ Œ๋”๋งํ•˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•ฉ๋‹ˆ๋‹ค

๊ธฐ์กด์˜ Batch

import { useState } from "react";

function Counter() {
	const [count, setCount] = useState(0);

	function increaseCountThree() {
		// ์•„๋ž˜์˜ ์ž‘์—…์€ ๋ชจ๋‘ ์ผ๊ด„์ ์œผ๋กœ ๋ฌถ์—ฌ ์ฒ˜๋ฆฌ๋œ๋‹ค. ํ•œ ๋ฒˆ์˜ ๋ฆฌ๋ Œ๋”๋ง๋งŒ ๋ฐœ์ƒํ•œ๋‹ค.
		setCount((prev) => prev + 1);
		setCount((prev) => prev + 1);
		setCount((prev) => prev + 1);
	}

	return (
		<div>
			<button onClick={increaseCountThree}>+1</button>
			<p>Count : {count}</p>
		</div>
	);
}

export default Counter;

React 18 ์ด์ „๊นŒ์ง€๋Š” batch ์—…๋ฐ์ดํŠธ๊ฐ€ย ๋ธŒ๋ผ์šฐ์ € ์ด๋ฒคํŠธ์™€ ๋‚ด์žฅ ํ›…์—์„œ๋งŒ ์ž‘๋™ํ•˜์˜€์Šต๋‹ˆ๋‹ค. ์ฆ‰, ๋น„๋™๊ธฐ ์ž‘์—…(romise, setTimeout ๋“ฑ)์ด๋‚˜ Native Event Handler ๋“ฑ์—์„œ ๋ฐœ์ƒํ•˜๋Š” state ์—…๋ฐ์ดํŠธ๋Š” batch ์—…๋ฐ์ดํŠธ๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.ย 

  • ์™œ๋ƒํ•˜๋ฉด ์ด์ „์—๋Š”ย ๋ธŒ๋ผ์šฐ์ €์˜ ์ด๋ฒคํŠธ๊ฐ€ ์‹คํ–‰๋˜๋Š” ์ค‘์—๋งŒย Batching ์ž‘์—…์„ ์ˆ˜ํ–‰ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ด๋ฒคํŠธ๊ฐ€ ์ข…๋ฃŒ๋œ ํ›„์— ์‹คํ–‰๋˜๋Š” ๊ฒฝ์šฐ๋Š” Batching ์ž‘์—…์ด ๋ถˆ๊ฐ€๋Šฅํ–ˆ์Šต๋‹ˆ๋‹ค.

์ด ๊ฒฝ์šฐ์—๋Š” ์ปดํฌ๋„ŒํŠธ๊ฐ€ state ์—…๋ฐ์ดํŠธ๋งˆ๋‹ค ๋ฆฌ๋ Œ๋”๋ง๋˜์–ด ์„ฑ๋Šฅ ์ €ํ•˜์™€ ๋ฒ„๊ทธ ๋ฐœ์ƒ์˜ ์œ„ํ—˜์ด ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

๋ฌธ์ œ์ 

function App() {
	const [count, setCount] = useState(0);
	const [flag, setFlag] = useState(false);

	function handleClick() {
		fetchSomething().then(() => {
			// React 17 ์ด์ „์˜ ๋ฒ„์ „์—์„œ๋Š” ํ•ด๋‹น ์ž‘์—…์„ Batching ์ฒ˜๋ฆฌํ•˜์ง€ ์•Š๋Š”๋‹ค.
			// ์™œ๋ƒํ•˜๋ฉด ํ•ด๋‹น ์ž‘์—…์€ ์ด๋ฒคํŠธ๊ฐ€ ์ข…๋ฃŒ๋œ ์ดํ›„ (100ms ๋’ค) ์— ์‹คํ–‰๋˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.
			setCount((c) => c + 1); // ๋ฆฌ๋ Œ๋”๋ง ์œ ๋ฐœ
			setFlag((f) => !f); // ๋ฆฌ๋ Œ๋”๋ง ์œ ๋ฐœ
		});
	}

	return (
		<div>
			<button onClick={handleClick}>Next</button>
			<h1 style={{ color: flag ? "blue" : "black" }}>{count}</h1>
		</div>
	);
}

function fetchSomething() {
	return new Promise((resolve) => setTimeout(resolve, 100));
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

state update ์ž‘์—…์ด ๋น„๋™๊ธฐ์ ์œผ๋กœ ์ฒ˜๋ฆฌ๋˜์–ด Event๊ฐ€ ์ข…๋ฃŒ๋œ ํ›„์— ์‹คํ–‰๋˜๊ธฐ ๋•Œ๋ฌธ์—, React์˜ Batching ์ž‘์—…์— ๊ฑธ๋ฆฌ์ง€ ์•Š์•„ ๋‘ ์ฐจ๋ก€ ๋ฆฌ๋ Œ๋”๋ง์„ ์œ ๋ฐœ์‹œ์ผฐ๋‹ค.

React์˜ ๋น„๊ณต์‹์  API unstable_batchedUpdates()๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๊ฐ•์ œ ๋ฐฐ์น˜ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ํ•ด์š”! (18๋ฒ„์ „ ์ด์ „์—.. ์ง€๊ธˆ์€ ์‚ฌ์šฉํ•  ํ•„์š”๊ฐ€ ์—†์Œ)

Automatic Batching

React 18์—์„œ๋Š” createRoot๋ฅผ ํ†ตํ•ดย Automatic Batching์ด๋ผ๋Š” ๊ฐœ์„ ๋œ ๋ฒ„์ „์˜ batch ์—…๋ฐ์ดํŠธ๋ฅผ ๋„์ž…ํ–ˆ์Šต๋‹ˆ๋‹ค

Automatic Batching์€ย ๋ชจ๋“  state ์—…๋ฐ์ดํŠธ๋ฅผ ์–ด๋””์„œ ์™”๋Š”์ง€์™€ ์ƒ๊ด€์—†์ด ์ž๋™์œผ๋กœ batch ์—…๋ฐ์ดํŠธํ•˜๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค. ์ฆ‰, timeout, promise, ๋„ค์ดํ‹ฐ๋ธŒ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ ๋“ฑ ๋ชจ๋“  ์ด๋ฒคํŠธ์—์„œ ๋ฐœ์ƒํ•˜๋Š” state ์—…๋ฐ์ดํŠธ๋„ React์—์„œ ์ œ๊ณตํ•˜๋Š” ์ด๋ฒคํŠธ์™€ ๋™์ผํ•˜๊ฒŒ batch ์—…๋ฐ์ดํŠธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.ย ์ด๋ฅผ ํ†ตํ•ด ๋ Œ๋”๋ง์„ ์ตœ์†Œํ™”ํ•˜๊ณ , ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ๋” ๋‚˜์€ ์„ฑ๋Šฅ์„ ๊ธฐ๋Œ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ์ด์ „ ๋ฒ„์ „์—์„œ์˜ React์—์„œ๋Š” componentDidUpdate()๊ฐ€ ์‹คํ–‰๋  ๋•Œ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ํ™•์ธํ•˜๊ณ  ๋ชจ์•„์„œ ์—…๋ฐ์ดํŠธ๋ฅผ ์ฒ˜๋ฆฌํ–ˆ์ง€๋งŒ, React 18๋ถ€ํ„ฐ๋Š” ๋ Œ๋”๋ง ๊ฒฐ๊ณผ๋ฅผ ์ผ์‹œ์ ์ธ ๋ฉ”๋ชจ๋ฆฌ์— ์ €์žฅํ•˜์—ฌ ์ผ๊ด„ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

์ € ์œ„์˜ ์ฝ”๋“œ๋ฅผ ์ง€๊ธˆ react๋กœ ํ•˜๋ฉด batch๊ฐ€ ์ž˜ ๋˜๋Š”๊ฑธ ๋ณผ์ˆ˜ ์žˆ์–ด์š”

์ถ”๊ฐ€์ ์œผ๋กœ ReactDOM.flushSync()

react-dom ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ์ถ”๊ฐ€๋œ ReactDOM.flushSync() ๋ฉ”์„œ๋“œ๋Š” Auto Batching ์„ ๋ฌด์‹œํ•˜๊ณ  ์ฆ‰์‹œ DOM์„ ๋ Œ๋”๋งํ•ด์ค๋‹ˆ๋‹ค.
React ์—์„œ๋Š” ๊ณต์‹์ ์œผ๋กœ ํ•ด๋‹น ๋ฉ”์„œ๋“œ์˜ ์‚ฌ์šฉ์„ ์ถ”์ฒœํ•˜์ง„ ์•Š์œผ๋ฉฐ (de-opt case), ํ•„์š”ํ•œ ์ƒํ™ฉ์ด ์žˆ์„ ๊ฒฝ์šฐ์—๋งŒ ์‚ฌ์šฉํ•  ๊ฒƒ์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค.

[2] ํด๋ž˜์Šคํ˜• ์ปดํฌ๋„ŒํŠธ์—์„œ ํ•จ์ˆ˜ํ˜• ์ปดํฌ๋„ŒํŠธ๋กœ ๋ฐ”๋€ ์ด์œ 

๊ณต๋ถ€ํ•˜๋ฉด์„œ ์–ด๋–ค ์–ด๋ ค์›€์ด ์žˆ์—ˆ๋‚˜์š”?

TodoList ํ”„๋กœ์ ํŠธ state ๊ด€๋ฆฌ์™€ ๋ฆฌ๋žœ๋”๋ง ์ตœ์ ํ™”

ํŽ˜์–ดํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ์•„์ฃผ ํ•˜๋ฃจ์ข…์ผ ํ•˜๋ฉด์„œ state ๊ด€๋ฆฌ์™€ ๋ฆฌ๋žœ๋”๋ง์— ๋Œ€ํ•œ ์ด์Šˆ๋ฅผ ๋Š์ž„์—†์ด ๋งˆ์ฃผ์ณค๋‹ค. ์ •๋ง state๊ฐ€ ๋งŽ์•„์ง€๋‹ค ๋ณด๋‹ˆ ํ—ท๊ฐˆ๋ฆฌ๊ณ , ๊ทธ๋กœ ์ธํ•ด ๋ถˆํ•„์š”ํ•œ ๋ Œ๋”๋ง์ด ๊ณ„์† ๋ฐœ์ƒํ•˜๋Š” ๋ฌธ์ œ๊ฐ€ ์ƒ๊ฒผ๋‹ค. ์ด์— ๋Œ€ํ•œ ์šฐ๋ฆฌ์˜ ๊นŠ์€ ๊ณ ๋ฏผ์€ ํšŒ๊ณ ๋•Œ ํ’€์–ด๋ณด๊ธฐ๋กœ ํ•˜๊ณ ..

recoil, redux ๋“ฑ์˜ ์ƒํƒœ๊ด€๋ฆฌ ํ”„๋กœ๊ทธ๋žจ์˜ ํ•„์š”์„ฑ์„ ๋ผˆ์ €๋ฆฌ๊ฒŒ ๋Š๋ผ๋Š” ์ˆœ๊ฐ„์ด์—ˆ๋‹ค. state๊ฐ€ ์—ฌ๊ธฐ์ €๊ธฐ ํฉ์–ด์ ธ์žˆ์œผ๋‹ˆ ๊ฐ๋‹นํ•˜๊ธฐ๊ฐ€ ๋งค์šฐ ํž˜๋“ค์—ˆ๋‹ค.. ์ด๋ฒˆ weekly์— ๋„์ž…ํ•ด๋ณผ๊นŒ? ์‹ถ์—ˆ์ง€๋งŒ, ์•„์ง์€ contextAPI๋กœ ์ถฉ๋ถ„ํžˆ ๊ตฌํ˜„ํ•ด๋ณด๊ณ , ๋‹ค์Œ์ฃผ๋‚˜ ๋‹ค๋ฅธ ์ฃผ๊ฐ„์— ๋˜ ์ด์–ด์„œ ํ•˜๊ฒŒ ๋œ๋‹ค๋ฉด ๋„์ž…์„ ํ•ด๋ณด๋Š” ๊ฑธ๋กœ..!!!

์ด ์ด์Šˆ ๋•Œ๋ฌธ์— ์ƒ๊ฐ๋ณด๋‹ค ๊ธฐ๋Šฅ๊ตฌํ˜„์„ ๋‹ค ๋ชปํ•ด์„œ ์•„์‰ฝ๋‹ค.

์‹œ๊ฐ„๊ด€๋ฆฌ์— ๋Œ€ํ•œ ๊ณ ๋ฏผ

ํ”„๋กœ์ ํŠธ๋ฅผ ํ•จ๊ป˜ ํ•˜๋‹ค๋ณด๋ฉด ์ •๋ง ๋ฐค์„ ์„ธ๋„ ๋ ๋งŒํผ ์žฌ๋ฏธ์žˆ์–ด์„œ ์‹œ๊ฐ„์ด ๊ฐ€๋Š” ์ค„ ๋ชจ๋ฅด๊ฒ ๋‹ค. ๊ทธ๋ž˜์„œ ์˜ค๋Š˜๋„ ๊ฐœ์ธํ•™์Šต์— ๋Œ€ํ•œ ์‹œ๊ฐ„์„ ๋งŽ์ด ์Ÿ์ง€ ๋ชปํ•œ ๊ฒƒ ๊ฐ™์•„์„œ ์•„์‰ฌ์› ๋‹ค. ๊ฐœ์ธ์˜ ์„ฑ์žฅ์— ์ด ๋‘˜ ๋ชจ๋‘ ๋งค์šฐ ์ค‘์š”ํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ์ด ์ ์ ˆํ•œ ๋‚˜๋งŒ์˜ ํŠธ๋ ˆ์ด๋“œ์˜คํ”„๋ฅผ ์ฐพ์•„์•ผํ•  ๊ฒƒ๊ฐ™๋‹ค.

๋‚ด์ผ์˜ ๋‚˜๋Š” ๋ฌด์—‡์„ ๊ณต๋ถ€ํ•ด์•ผ ํ• ๊นŒ์š”?

  • ํŽ˜์–ดํ”„๋กœ๊ทธ๋ž˜๋ฐ todolist ๊ธฐ๋Šฅ ๊ตฌํ˜„ ์™„๋ฃŒ (์ˆ˜์ •, ์‚ญ์ œ, ๋กœ๊ทธ์ธ)
  • ์•Œ๊ณ ๋ฆฌ์ฆ˜ 1๋ฌธ์ œ
  • reacd swiper, dnd ๊ณต๋ถ€

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