๐ŸŽ‰ berenickt ๋ธ”๋กœ๊ทธ์— ์˜จ ๊ฑธ ํ™˜์˜ํ•ฉ๋‹ˆ๋‹ค. ๐ŸŽ‰
Front
09-Render Props

1. Render Props

Render Props = ๋ฌด์—‡์„ ๋ Œ๋”๋ง ํ• ์ง€ ์ปดํฌ๋„ŒํŠธ์— ์•Œ๋ ค์ฃผ๋Š” ํ•จ์ˆ˜

  • React ์ปดํฌ๋„ŒํŠธ ๊ฐ„์— ์ฝ”๋“œ๋ฅผ ๊ณต์œ ํ•˜๊ธฐ ์œ„ํ•ด ํ•จ์ˆ˜ props๋ฅผ ์ด์šฉํ•˜๋Š” ๋ฒ•

  • ์ฝ”๋“œ ์žฌ์‚ฌ์šฉ์„ ์œ„ํ•œ ๋ฐฉ๋ฒ• ์ค‘ ํ•˜๋‚˜ ( Composition | HOC | Render Props ... )

  • Render = (๋ญ”๊ฐ€) ์ œ๊ณต, ์ฃผ๋‹ค

  • Render Props๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” React Router, Downshift, Formik

  • c.f. https://ko.reactjs.org/docs/render-props.html

1
<DataProvider render={data => <h1>Hello {data.target}</h1>} />

Render Props ํŒจํ„ด์œผ๋กœ ๊ตฌํ˜„๋œ ์ปดํฌ๋„ŒํŠธ๋Š” ์ž์ฒด์ ์œผ๋กœ ๋ Œ๋”๋ง ๋กœ์ง์„ ๊ตฌํ˜„ํ•˜๋Š” ๋Œ€์‹ , React ์—˜๋ฆฌ๋จผํŠธ ์š”์†Œ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ณ  ์ด๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.


2. ํšก๋‹จ ๊ด€์‹ฌ์‚ฌ(Cross-Cutting Concerns)

Cross-Cutting Concerns

  • ์ปดํฌ๋„ŒํŠธ A, B, C ๊ฐ„์˜ ๊ณตํ†ต๋œ ๊ธฐ๋Šฅ์„ ํ•  ๋–„, ํ•ต์‹ฌ ์ ์ธ ๊ธฐ๋Šฅ์ด ์•„๋‹Œ ์ค‘๊ฐ„์ค‘๊ฐ„ ์‚ฝ์ž…๋˜์–ด์•ผ ํ•  ๊ธฐ๋Šฅ๋“ค
  • e.g. ๋กœ๊น…, ๋ณด์•ˆ, ํŠธ๋žœ์žญ์…˜ ์ฒ˜๋ฆฌ ๋“ฑ ๋น„์ฆˆ๋‹ˆ์Šค ํ•ต์‹ฌ์ ์ธ ๊ธฐ๋Šฅ์ด ์•„๋‹Œ ๋‹ค์–‘ํ•œ ํšก๋‹จ ๊ด€์‹ฌ์ด ๋ฐœ์ƒ
  • c.f. ๊ด€์  ์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ(Aspect Oriented Programming; AOP)
    • ํšก๋‹จ ๊ด€์‹ฌ์‚ฌ(cross-cutting concern)์˜ ๋ถ„๋ฆฌ๋ฅผ ํ—ˆ์šฉํ•จ์œผ๋กœ์จ, ๋ชจ๋“ˆ์„ฑ์„ ์ฆ๊ฐ€์‹œํ‚ค๋Š” ๊ฒƒ์ด ๋ชฉ์ ์ธ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ํŒจ๋Ÿฌ๋‹ค์ž„
    • ๋‹ค์‹œ ๋งํ•ด, ์ฝ”๋“œ ์ƒ์—์„œ ๊ฐ๊ฐ์˜ ๊ด€์ ์„ ํ•ต์‹ฌ์ ์ธ ๊ด€์ ๊ณผ, ๋ถ€๊ฐ€์ ์ธ ๊ด€์ ์œผ๋กœ ๋‚˜๋ˆ„์–ด๋ณด๊ณ ,
      • ๊ทธ ๊ด€์ ์„ ๊ธฐ์ค€์œผ๋กœ ๊ฐ๊ฐ ๋ถ„๋ฆฌํ•˜๋Š” ๊ฒƒ์„ ์˜๋ฏธ

3. ์˜ˆ์‹œ

๋งˆ์šฐ์Šค๋ฅผ ๋”ฐ๋ผ๋‹ค๋‹ˆ๋Š” ์ด๋ฏธ์ง€๋ฅผ ๋ถ™์ด๊ณ  ์‹ถ์œผ๋ฉด?

1
import React, { useState } from 'react'
2
import styled from 'styled-components'
3
4
// ๋งˆ์šฐ์Šค๊ฐ€ ์›€์ง์ผ ๋•Œ๋งˆ๋‹ค ์ขŒํ‘œ๋ฅผ ์•Œ ์ˆ˜ ์žˆ๋Š” Mouse ์ปดํฌ๋„ŒํŠธ
5
export default function Mouse() {
6
const [mousePosition, setMousePosition] = useState({ x: 0, y: 0 })
7
8
const handleMouseMove = event => {
9
setMousePosition({ x: event.clientX, y: event.clientY })
10
}
11
12
return (
13
<div style={{ height: '100vh' }} onMouseMove={handleMouseMove}>
14
<Image position={mousePosition} />
15
Mouse X = {mousePosition.x} Y = {mousePosition.y}
16
</div>
17
)
18
}
19
20
// styled components ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์ด๋ฏธ์ง€ ๋Œ€์‹  ์‚ฌ์šฉํ•จ
21
const Image = styled.div`
22
width: 30px;
23
height: 30px;
24
background-color: red;
25
position: absolute;
26
left: ${({ position }) => position.x}px;
27
top: ${({ position }) => position.y}px;
28
`

์œ„์™€ ๊ฐ™์ด ํ•˜๋“œ์ฝ”๋”ฉํ•˜๋ฉด, ๋‹ค๋ฅธ ์ด๋ฏธ์ง€๋ฅผ ๋ Œ๋”๋ง ํ•˜๊ณ  ์‹ถ์„ ๋• ๋˜๋‹ค์‹œ ํ•˜๋“œ์ฝ”๋”ฉ์œผ๋กœ ๋ฐ”๊ฟ”์•ผ ํ•œ๋‹ค.

1
import Mouse from './components/renderProps/Mouse'
2
import Image from './components/renderProps/Image'
3
4
export default function App() {
5
return (
6
<div>
7
{/* Mouse ์ปดํฌ๋„ŒํŠธ์— render props๋กœ ๋ Œ๋”๋ง ํ•  ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋„˜๊น€ */}
8
<Mouse render={position => <Image position={position} />} />
9
</div>
10
)
11
}

๊ทธ๋ž˜์„œ ์žฌ์‚ฌ์šฉ์„ ์œ„ํ•ด์„œ๋Š” Mouse ์ปดํฌ๋„ŒํŠธ์— render props๋กœ ๋ Œ๋”๋ง ํ•  ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋„˜๊ฒจ์ค€๋‹ค.

1
import React, { useState } from 'react'
2
3
// 1. props๋กœ render๋ฅผ ๋ฐ›์Œ
4
export default function Mouse({ render }) {
5
const [mousePosition, setMousePosition] = useState({ x: 0, y: 0 })
6
7
const handleMouseMove = event => {
8
setMousePosition({ x: event.clientX, y: event.clientY })
9
}
10
11
return (
12
<div style={{ height: '100vh' }} onMouseMove={handleMouseMove}>
13
{render(mousePosition)}
14
๋งˆ์šฐ์Šค์˜ X์ขŒํ‘œ = {mousePosition.x}, Y์ขŒํ‘œ = {mousePosition.y}
15
</div>
16
)
17
}

Mouse ์ปดํฌ๋„ŒํŠธ์—์„œ props๋กœ render๋ฅผ ๋ฐ›์•„์„œ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜๋ฉด ์–ด๋–ค ์ด๋ฏธ์ง€๋ฅผ ๋„˜๊ฒจ์ฃผ์–ด๋„ ์‚ฌ์šฉ ๊ฐ€๋Šฅ


[์ฐธ๊ณ ]