YesCoding

Go to English
search:

[React] Component๋“ค์˜ rendering ์ˆœ์„œ์™€ event capture/bubble

thumbnail render order

1. ๋ฆฌ์•กํŠธ ๋ถ€๋ชจ/์ž์‹๊ฐ„์˜ ๋ Œ๋”๋ง ์ˆœ์„œ 2. ๋ถ€๋ชจ ์ž์‹ ๊ด€๊ณ„ ์ปดํฌ๋„ŒํŠธ๋“ค์˜ ์ด๋ฒคํŠธ ์ „ํŒŒ ๋ฅผ ํ…Œ์ŠคํŠธํ•˜๋ฉด์„œ ๊ณต๋ถ€ํ•œ ๊ฒƒ๋“ค์„ ์ •๋ฆฌํ–ˆ์Šต๋‹ˆ๋‹ค.

๋ Œ๋”๋ง ์ˆœ์„œ

Depth1, Depth2, Depth3 ์ด 3 ๊ฐœ์˜ ์ปดํฌ๋„ŒํŠธ๋“ค์„ Depth1 > Depth2 > Depth3 ์œผ๋กœ ๊ตฌ์กฐ๋ฅผ ์งœ๊ณ  ๋ Œ๋”๋ง ๋กœ๊ทธ์™€ devTool์— ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์–ด๋–ป๊ฒŒ ์ฐํžˆ๋Š” ์ง€ ํ™•์ธํ•ด๋ดค๋‹ค.

์ฝ”๋“œ

import './App.css'; import {Helmet} from "react-helmet"; import Depth1 from './render-order/depth1'; function App() { return ( <div className="App"> <Helmet htmlAttributes={{ lang: 'ko'}}> <title>study</title> </Helmet> <Depth1 /> </div> ); } export default App; ---- import Depth2 from './depth2'; const Depth1 = () => { console.log('Depth 1 render') return ( <> <div>I'm Depth1</div> <Depth2 /> </> ) } export default Depth1; ----- import Depth3 from './depth3'; const Depth2 = () => { console.log('Depth 2 render') return ( <> <div>I'm Depth2</div> <Depth3 /> </> ) } export default Depth2; --- const Depth3 = () => { console.log('Depth 3 render') return ( <> <div>I'm Depth3</div> </> ) } export default Depth3;

์ปดํฌ๋„ŒํŠธ ๋ Œ๋”๋ง devTool

์ปดํฌ๋„ŒํŠธ ๋ Œ๋”๋ง devTool

๋ Œ๋”๋ง ์ˆœ์„œ๋Š” ๋ถ€๋ชจ โ†’ ์ž์‹ App โ†’ Depth1 โ†’ Depth2 โ†’ Depth3 ๋กœ ๋‚˜ํƒ€๋‚œ๋‹ค.

Event Bubbling / Capturing

case 1) depth1, depth2, depth3 ์— onclick ์ด๋ฒคํŠธ ๋ถ™์ธ ๊ฒฝ์šฐ ์ด๋ฒคํŠธ ๋ฒ„๋ธ”๋ง (event bubbling) ๊ด€์ฐฐ

function App() { return ( <div className="App"> <Helmet htmlAttributes={{ lang: 'ko'}}> <title>study</title> </Helmet> <Depth1 /> </div> ); } export default App; ---- import Depth2 from './depth2'; const Depth1 = () => { console.log('Depth 1 render') return ( <div onClick={() => console.log('depth 1 log')}> <div>I'm Depth1</div> <Depth2 /> </div> ) } export default Depth1; ----- import Depth3 from './depth3'; const Depth2 = () => { console.log('Depth 2 render') return ( <div onClick={() => console.log('depth 2 log')}> <div>I'm Depth2</div> <Depth3 /> </div> ) } export default Depth2; --- const Depth3 = () => { console.log('Depth 3 render') return ( <div onClick={() => console.log('depth 3 log')}> <div>I'm Depth3</div> </div> ) } export default Depth3;

์œ„ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๊ณ  Depth3 ๊ณผ Depth2 ๋ฅผ ํด๋ฆญํ•˜๋ฉด ๋‹ค์Œ ์ด๋ฏธ์ง€์ฒ˜๋Ÿผ ์ด๋ฒคํŠธ ๋ฒ„๋ธ”๋ง (event bubbling)์ด ์ผ์–ด๋‚œ๋‹ค.

depth 3 ํด๋ฆญํ–ˆ์„ ๋•Œ

depth 3 ํด๋ฆญํ–ˆ์„ ๋•Œ

depth 2 ํด๋ฆญํ–ˆ์„ ๋•Œ

depth 2 ํด๋ฆญํ–ˆ์„ ๋•Œ

case 2) depth1 context ์—์„œ onclick ํ•จ์ˆ˜ ๋งŒ๋“ค๊ณ  depth 2๋กœ ์ƒ์†์‹œํ‚ค๋Š” ๊ฒฝ์šฐ ์ด๋ฒคํŠธ ๋ฒ„๋ธ”๋ง

import Depth2 from './depth2'; const Depth1 = () => { console.log('Depth 1 render') const handleOnClick = () => { console.log('depth 1 log') }; return ( <div onClick={handleOnClick}> <div>I'm Depth1</div> <Depth2 onClick={handleOnClick} /> </div> ) } export default Depth1; --- import Depth3 from './depth3'; const Depth2 = (props) => { console.log('Depth 2 render') return ( <div onClick={() => props.handleOnClick}> // depth 1์—์„œ ์ƒ์†์‹œ์ผฐ๋‹ค. <div>I'm Depth2</div> <Depth3 /> </div> ) } export default Depth2; --- const Depth3 = () => { console.log('Depth 3 render') return ( <div onClick={() => console.log('depth 3 log')}> <div>I'm Depth3</div> </div> ) } export default Depth3;

react event 3

react_event_3

depth3 ์„ ํด๋ฆญํ•˜๋ฉด, ์ด๋ฒคํŠธ ๋ฒ„๋ธ”๋ง์ด ๋˜์–ด depth2์˜ props.handleOnClick ์ด ์‹คํ–‰๋˜๊ณ , ์œ„ ์ด๋ฏธ์ง€์ฒ˜๋Ÿผ depth1 log ๊ฐ€ ์ฐํžŒ๋‹ค. ์ด๋ฒคํŠธ ๋ฒ„๋ธ”๋ง์€ document ๊ฐ์ฒด๋ฅผ ๋งŒ๋‚  ๋•Œ๊นŒ์ง€ onClick ์ด๋ฒคํŠธ๋ฅผ ๋งŒ๋‚ ๋•Œ๋งˆ๋‹ค ๋™์ž‘ํ•œ๋‹ค.

case 3) depth1,2,3 ์—์„œ ๋ชจ๋‘ ์ด๋ฒคํŠธ ์บก์ณ๋ง ๊ฑธ๊ณ  ํด๋ฆญํ•œ ๊ฒฝ์šฐ

import Depth2 from './depth2'; const Depth1 = () => { console.log('Depth 1 render') const handleOnClick = () => { console.log('depth 1 log') }; return ( <div onClick={handleOnClick} onClickCapture={() => console.log('depth 1 capture log')}> <div>I'm Depth1</div> <Depth2 /> </div> ) } export default Depth1; --- import Depth3 from './depth3'; const Depth2 = (props) => { console.log('Depth 2 render') return ( <div onClick={() => console.log('depth 2 log')} onChange={() => console.log('depth2 onChange')} onClickCapture={() => console.log('depth 2 capture log')}> <div>I'm Depth2</div> <Depth3 /> </div> ) } export default Depth2; --- const Depth3 = () => { console.log('Depth 3 render') return ( <div onClick={() => console.log('depth 3 log')} onClickCapture={() => console.log('depth 3 capture log')}> <div>I'm Depth3</div> </div> ) } export default Depth3;

์œ„ ์ฝ”๋“œ๋Š” depth1, depth2, depth3 ์— bubble ๋˜๋Š” click ๊ณผ capture ๋˜๋Š” click ์„ ๋‘๊ฐœ์”ฉ ๋ชจ๋‘ ๊ฑด ์ƒํƒœ์ด๋‹ค. ์—ฌ๊ธฐ์„œ depth3 ์„ ํด๋ฆญํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋กœ๊ทธ๊ฐ€ ์ฐํžŒ๋‹ค.

react event 4

react_event_4

๋จผ์ € depth1 โ†’ depth2 โ†’ depth3 ์ˆœ์œผ๋กœ ์ด๋ฒคํŠธ๊ฐ€ ์บก์ณ๋ง ๋˜๊ณ , depth3 โ†’ depth2 โ†’ depth1 ์ˆœ์œผ๋กœ ์ด๋ฒคํŠธ๊ฐ€ ๋ฒ„๋ธ”๋ง๋œ๋‹ค.

๊ทธ๋Ÿผ depth1 ์—์„œ ์บก์ณ๋ง ์ฝ”๋“œ๋ฅผ ์ œ๊ฑฐํ•˜๊ณ  depth3 ์„ ํด๋ฆญํ•˜๋ฉด ์–ด๋–ป๊ฒŒ ๋ ๊นŒ?

react event 5

react_event_5

์บก์ณ๋ง์„ ๊ฑธ์–ด๋‘” depth2 ๋ถ€ํ„ฐ ์บก์ณ๋ง ์ด๋ฒคํŠธ๊ฐ€ ์•„๋ž˜๋กœ ์ „ํŒŒ๋œ๋‹ค. ์•„์ง ๋ฒ„๋ธ”๋ง ํด๋ฆญ ์ด๋ฒคํŠธ๋Š” depth1 ์— ๋‚จ์•„์žˆ๋Š” ์ƒํƒœ์—ฌ์„œ ๋ฒ„๋ธ”๋ง ์ด๋ฒคํŠธ๋Š” 3 โ†’ 2 โ†’ 1 ์ˆœ์œผ๋กœ ์ „ํŒŒ๋œ๋‹ค.

๊ทธ๋Ÿผ depth 2 ์—์„œ๋งŒ ์บก์ณ๋ง ์ฝ”๋“œ๋ฅผ ์ œ๊ฑฐํ•˜๊ณ  depth3 ์„ ํด๋ฆญํ•˜๋ฉด ์–ด๋–ป๊ฒŒ ๋ ๊นŒ?

react event 6

react_event_6

์บก์ณ๋ง์„ ์•ˆ ๊ฑธ์–ด๋‘” depth 2 ๋ฅผ ๊ฑด๋„ˆ ๋›ฐ๊ณ  1 โ†’ 3 ์œผ๋กœ ๊ฐ”๋‹ค๊ฐ€ 3 โ†’ 2 โ†’ 1 ์ˆœ์œผ๋กœ ์ด๋ฒคํŠธ๊ฐ€ ๋ฒ„๋ธ”๋ง๋œ๋‹ค.

๐Ÿ’ก๐Ÿ’ก๐Ÿ’ก๐Ÿ‘ฉ๐Ÿปโ€๐Ÿ’ป๐Ÿ‘ฉ๐Ÿปโ€๐Ÿ’ป

ํด๋ฆญ ์ด๋ฒคํŠธ๋“ค์ด ๋ฒ„๋ธ”๋ง ๋˜๊ณ  ์บก์ณ๋ง ๋˜๋Š” ๋™์•ˆ์—๋„ ์ปดํฌ๋„ŒํŠธ์˜ ๋ฆฌ๋ Œ๋”๊ฐ€ ์ผ์–ด๋‚˜์ง€ ์•Š๋Š”๋‹ค.

์™œ๋ƒ? ๋ถ€๋ชจ depth1 ์˜ props ์ด๋‚˜ state ๊ฐ€ ๋ณ€ํ•˜์ง€ ์•Š์•„ depth1 ์ด ๋ฆฌ๋ Œ๋”๊ฐ€ ์•ˆ๋˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

(2, 3 ๋„ ๋งˆ์ฐฌ๊ฐ€์ง€์ธ๋ฐ, ๋งŒ์•ฝ depth1 ์ด ๋ฆฌ๋ Œ๋”ํ•˜๋ฉด ํ•จ์ˆ˜ํ˜• >์ปดํฌ๋„ŒํŠธ์—์„œ๋Š” ์ž์‹ ์ปดํฌ๋„ŒํŠธ๋“ค์€ prop, state ์ƒ๊ด€์—†์ด ๋ฌด์กฐ๊ฑด ๋ฆฌ๋ Œ๋” ๋œ๋‹ค)

ยฉ Copyright 2022, yesCoding