반응형
1. Render Props
재사용의 한 방법이다. ( Composition, HOC, render props ... )
React 컴포넌트 간에 코드를 공유하기 위해 함수 props를 이용하는 간단한 기능이다.
2. 사용 이유
class MouseTracker extends React.Component {
constructor(props) {
super(props);
this.handleMouseMove = this.handleMouseMove.bind(this);
this.state = { x: 0, y: 0 };
}
handleMouseMove(event) {
this.setState({
x: event.clientX,
y: event.clientY
});
}
render() {
return (
<div style={{ height: '100vh' }} onMouseMove={this.handleMouseMove}>
<h1>Move the mouse around!</h1>
<p>The current mouse position is ({this.state.x}, {this.state.y})</p>
</div>
);
}
}
웹페이지에서 마우스 위치를 추적하는 로직이다.
스크린 주위로 마우스 커서를 움직이면, 컴포넌트가 마우스의 (x,y) 좌표를 <p>에 나타낸다.
이것을 재사용할 수 있게 만들려면 어떻게 해야할까?
class Mouse extends React.Component {
constructor(props) {
super(props);
this.handleMouseMove = this.handleMouseMove.bind(this);
this.state = { x: 0, y: 0 };
}
handleMouseMove(event) {
this.setState({
x: event.clientX,
y: event.clientY
});
}
render() {
return (
<div style={{ height: '100vh' }} onMouseMove={this.handleMouseMove}>
{/* ...하지만 <p>가 아닌 다른것을 렌더링하려면 어떻게 해야 할까요? */}
<p>The current mouse position is ({this.state.x}, {this.state.y})</p>
</div>
);
}
}
class MouseTracker extends React.Component {
render() {
return (
<>
<h1>Move the mouse around!</h1>
<Mouse />
</>
);
}
}
<Mouse> 컴포넌트가 마우스의 움직임 이벤트를 감지하고 위치를 저장하는 행위를 하게 만들었다.
하지만 추가로 마우스 주변에 고양이 그림을 보여주는 <Cat> 컴포넌트를 추가할 경우엔 어떻게 해야할까?
class Cat extends React.Component {
render() {
const mouse = this.props.mouse;
return (
<img src="/cat.jpg" style={{ position: 'absolute', left: mouse.x, top: mouse.y }} />
);
}
}
class MouseWithCat extends React.Component {
constructor(props) {
super(props);
this.handleMouseMove = this.handleMouseMove.bind(this);
this.state = { x: 0, y: 0 };
}
handleMouseMove(event) {
this.setState({
x: event.clientX,
y: event.clientY
});
}
render() {
return (
<div style={{ height: '100vh' }} onMouseMove={this.handleMouseMove}>
{/*
여기서 <p>를 <Cat>으로 바꿀 수 있습니다. ... 그러나 이 경우
Mouse 컴포넌트를 사용할 때 마다 별도의 <MouseWithSomethingElse>
컴포넌트를 만들어야 합니다, 그러므로 <MouseWithCat>는
아직 정말로 재사용이 가능한게 아닙니다.
*/}
<Cat mouse={this.state} />
</div>
);
}
}
class MouseTracker extends React.Component {
render() {
return (
<div>
<h1>Move the mouse around!</h1>
<MouseWithCat />
</div>
);
}
}
<Mouse> 컴포넌트 안에 <Cat> 컴포넌트를 넣어 새로운 컴포넌트를 만들었다.
원하는 목표는 달성했지만 <Mouse> 컴포넌트가 언제든지 마우스 위치만을 추적할 수 있게 캡슐화는 못하였다.
오직 마우스 위치만 추적할 수 있는 <Mouse> 컴포넌트와 주변에 고양이를 그리는 <Cat> 컴포넌트를 캡슐화를 하면서
사용할 때 Render Props가 사용된다.
3. 사용하기
class Cat extends React.Component {
render() {
const mouse = this.props.mouse;
return (
<img src="/cat.jpg" style={{ position: 'absolute', left: mouse.x, top: mouse.y }} />
);
}
}
class Mouse extends React.Component {
constructor(props) {
super(props);
this.handleMouseMove = this.handleMouseMove.bind(this);
this.state = { x: 0, y: 0 };
}
handleMouseMove(event) {
this.setState({
x: event.clientX,
y: event.clientY
});
}
render() {
return (
<div style={{ height: '100vh' }} onMouseMove={this.handleMouseMove}>
{/*
<Mouse>가 무엇을 렌더링하는지에 대해 명확히 코드로 표기하는 대신,
`render` prop을 사용하여 무엇을 렌더링할지 동적으로 결정할 수 있습니다.
*/}
{this.props.render(this.state)}
</div>
);
}
}
class MouseTracker extends React.Component {
render() {
return (
<div>
<h1>Move the mouse around!</h1>
<Mouse render={mouse => (
<Cat mouse={mouse} />
)}/>
</div>
);
}
}
이제 <Mouse> 컴포넌트는 오직 마우스의 위치만 추적하고 부모로부터 받은 render를 화면에 출력해주는 기능을 한다.
그리고 <Cat> 컴포넌트도 <Mouse> 컴포넌트 안에서 호출되는 것이 아닌, 부모에서 호출되여 넘겨주는 방식이다.
즉, render props는 무엇을 렌더링할지 컴포넌트에 알려주는 함수이다.
반응형
'React > 패스트캠퍼스' 카테고리의 다른 글
[React - 기초] Reconciliation (0) | 2022.03.21 |
---|---|
[React - 기초] PropTypes (2) | 2022.03.19 |
[React - 기초] Portals (2) | 2022.03.17 |
[React - 기초] Memoization (2) | 2022.03.15 |
[React - 기초] Hooks (0) | 2022.03.10 |