React

[React] render props 한번 써보자

눙엉 2022. 2. 5. 16:56

1. Render Props란

"render prop"란, React 컴포넌트 간에 코드를 공유하기 위해 함수 props를 이용하는 간단한 테크닉입니다.

 

Render Props – React

A JavaScript library for building user interfaces

ko.reactjs.org

Render Props에 대해 React 공식문서에 이렇게 나온다.

 

render props 패턴으로 구현된 컴포넌트는 자체적으로 렌더링 로직을 구현하는 대신
react 엘리먼트 요소를 반환하고 이를 호출하는 함수를 사용한다.

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

 

2. 예시

공식문서를 바탕으로 함수형으로 만들어봤다.

 

Mouse 컴포넌트는 마우스가 움직일 때마다 좌표를 알 수 있는 컴포넌트다.

// Mouse Component

import React from "react";
import { useState } from "react";

export default function Mouse({ render }) {
  const [mousePosition, setMousePosition] = useState({ x: 0, y: 0 });

  const handleMouseMove = (event) => {
    setMousePosition({ x: event.clientX, y: event.clientY });
  };

  return (
    <div style={{ height: "100vh" }} onMouseMove={handleMouseMove}>
      Mouse X = {mousePosition.x} Y = {mousePosition.y}
    </div>
  );
}

 

마우스를 따라다니는 이미지를 붙이고 싶으면 하드코딩으로 만들 수 있다.

// Mouse Component에 이미지를 하드코딩으로 삽입

import React from "react";
import { useState } from "react";
import styled from "styled-components";

export default function Mouse() {
  const [mousePosition, setMousePosition] = useState({ x: 0, y: 0 });

  const handleMouseMove = (event) => {
    setMousePosition({ x: event.clientX, y: event.clientY });
  };

  return (
    <div style={{ height: "100vh" }} onMouseMove={handleMouseMove}>
      <Image position={mousePosition} />
      Mouse X = {mousePosition.x} Y = {mousePosition.y}
    </div>
  );
}

const Image = styled.div`
  width: 30px;
  height: 30px;
  background-color: red;
  position: absolute;
  left: ${({ position }) => position.x}px;
  top: ${({ position }) => position.y}px;
`;

styled components를 사용해서 Image 컴포넌트를 만들어서 이미지 대신 사용했다. 

하드코딩하게 되면 다른 이미지를 렌더링 하고 싶을 땐 또다시 하드코딩으로 바꿔야 한다.

 

// Mouse Component를 사용하는 곳에서 render props로 Image Component 추가

import "./App.css";
import Image from "./components/renderProps/Image";
import Mouse from "./components/renderProps/Mouse";

function App() {
  return (
    <div className="App">
      <Mouse
        render={(position) => {
          return <Image position={position} />;
        }}
      />
    </div>
  );
}

export default App;

이렇게 Mouse 컴포넌트에 render props로 렌더링 할 컴포넌트를 넘겨준다.

 

// Mouse Component

import React from "react";
import { useState } from "react";

export default function Mouse({ render }) {
  const [mousePosition, setMousePosition] = useState({ x: 0, y: 0 });

  const handleMouseMove = (event) => {
    setMousePosition({ x: event.clientX, y: event.clientY });
  };

  return (
    <div style={{ height: "100vh" }} onMouseMove={handleMouseMove}>
      {render(mousePosition)}
      Mouse X = {mousePosition.x} Y = {mousePosition.y}
    </div>
  );
}

이제 Mouse 컴포넌트에서 props로 render를 받아서 사용하게 되면 어떤 이미지를 넘겨주어도 사용 가능하다.

 

3. 결론

render prop은 무엇을 렌더링 할지 컴포넌트에 알려주는 함수다.

재사용성을 위해서 컴포넌트를 만들기 전에 한번 고민해보면 좋을 것 같다.