[React] Component๋ค์ rendering ์์์ event capture/bubble
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
๋ ๋๋ง ์์๋ ๋ถ๋ชจ โ ์์ 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 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
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
๋จผ์ depth1 โ depth2 โ depth3 ์์ผ๋ก ์ด๋ฒคํธ๊ฐ ์บก์ณ๋ง ๋๊ณ , depth3 โ depth2 โ depth1 ์์ผ๋ก ์ด๋ฒคํธ๊ฐ ๋ฒ๋ธ๋ง๋๋ค.
๊ทธ๋ผ depth1 ์์ ์บก์ณ๋ง ์ฝ๋๋ฅผ ์ ๊ฑฐํ๊ณ depth3 ์ ํด๋ฆญํ๋ฉด ์ด๋ป๊ฒ ๋ ๊น?
react_event_5
์บก์ณ๋ง์ ๊ฑธ์ด๋ depth2 ๋ถํฐ ์บก์ณ๋ง ์ด๋ฒคํธ๊ฐ ์๋๋ก ์ ํ๋๋ค. ์์ง ๋ฒ๋ธ๋ง ํด๋ฆญ ์ด๋ฒคํธ๋ depth1 ์ ๋จ์์๋ ์ํ์ฌ์ ๋ฒ๋ธ๋ง ์ด๋ฒคํธ๋ 3 โ 2 โ 1 ์์ผ๋ก ์ ํ๋๋ค.
๊ทธ๋ผ depth 2 ์์๋ง ์บก์ณ๋ง ์ฝ๋๋ฅผ ์ ๊ฑฐํ๊ณ depth3 ์ ํด๋ฆญํ๋ฉด ์ด๋ป๊ฒ ๋ ๊น?
react_event_6
์บก์ณ๋ง์ ์ ๊ฑธ์ด๋ depth 2 ๋ฅผ ๊ฑด๋ ๋ฐ๊ณ 1 โ 3 ์ผ๋ก ๊ฐ๋ค๊ฐ 3 โ 2 โ 1 ์์ผ๋ก ์ด๋ฒคํธ๊ฐ ๋ฒ๋ธ๋ง๋๋ค.
๐ก๐ก๐ก๐ฉ๐ปโ๐ป๐ฉ๐ปโ๐ป
ํด๋ฆญ ์ด๋ฒคํธ๋ค์ด ๋ฒ๋ธ๋ง ๋๊ณ ์บก์ณ๋ง ๋๋ ๋์์๋ ์ปดํฌ๋ํธ์ ๋ฆฌ๋ ๋๊ฐ ์ผ์ด๋์ง ์๋๋ค.
์๋? ๋ถ๋ชจ depth1 ์ props ์ด๋ state ๊ฐ ๋ณํ์ง ์์ depth1 ์ด ๋ฆฌ๋ ๋๊ฐ ์๋๊ธฐ ๋๋ฌธ์ด๋ค.
(2, 3 ๋ ๋ง์ฐฌ๊ฐ์ง์ธ๋ฐ, ๋ง์ฝ depth1 ์ด ๋ฆฌ๋ ๋ํ๋ฉด ํจ์ํ >์ปดํฌ๋ํธ์์๋ ์์ ์ปดํฌ๋ํธ๋ค์ prop, state ์๊ด์์ด ๋ฌด์กฐ๊ฑด ๋ฆฌ๋ ๋ ๋๋ค)