Web/[JS] FrontEnd

Props Drilling

ihl 2021. 6. 14. 19:05

1. Props Drilling

Props Drilling

  React에서 props로 컴포넌트간 데이터를 전달할 때 해당 데이터가 필요없는 컴포넌트에도 어쩔 수 없이 데이터가 전달해주어야 할 때가 있다. 위 그림에서 컴포넌트 A의 데이터를 컴포넌트 C로 전달하기 위해선 사이에 있는 컴포넌트 B를 거쳐야하는 것처럼 말이다. 이것이 Props Drilling(혹은 Threading)이다. 

 

  Props Drilling은 데이터 전달을 구현하는 가장 단순한 방법이지만 코드를 이해하기 어렵게 만든다. 그림을 다시 보자. 데이터 전달을 위해 컴포넌트 B는 필요하지 않은 데이터를 갖게되다. 또한 컴포넌트 A에서 B로 전달될 때와 B에서 C로 전달될 때 Property 이름이 변경된다면 어떨까? C에서 문제가 생겼을 때 해당 프라퍼티가 어디서 온 것인지 추적하기 어려워진다. 이러한 단점은 어플리케이션이 커져 컴포넌트의 깊이가 깊어질수록 심각해진다.

 

2. Avoid Props Drilling

 2-1. State Management

   Props Drilling을 피하기 위해선 컴포넌트들이 props를 전달하지 않고 Component 간에 값을 공유하도록 만들어야 한다. 따라서 Redux, Recoil와 같은 상태관리솔루션이 해결방법이 될 수 있다. React Context 공식문서에는 Context가 모든 컴포넌트를 통하지 않고 컴포넌트 간의 데이터를 전달할 수 있는 방법이라 적혀있다. 다만 Context API의 경우 데이터 변경 시 데이터를 구독하는 모든 컴포넌트들이 재렌더링 되므로 전역상태관리 솔루션으로 사용하기 보다는 지역적인 데이터 전달을 위해 사용하는 것이 좋다.

 

 2-2. Render Props

class TodoPage extends React.Component {
  handleDelete = todo => {
    const todos = this.state.todos.filter(t => t.id !== todo.id);
    this.setState({ todos });
  };

  render() {
    const { todos } = this.state;
    return (
      <div>
        <TodoList
          todos={todos}
          renderItem={todo => (
            <TodoItem
              todo={todo}
              onDelete={this.handleDelete}
            />
          )}
        />
      </div>
    );
  }
};

  render prop은 함수인 prop을 이용하여 React 컴포넌트간에 코드를 공유하는 기술이다. render prop은 컴포넌트가 무엇을 렌더링할지 알려준다. 위 코드는 todo 목록 페이지를 만들기 위한 코드이다. 코드에서 주목할 점은 TodoPage가 TodoList에게 TodoItem을 렌더링하는 로직을 정의하여 renderItem이란 이름의 prop으로 내려주고, TodoList에선 이를 자신이 가진 상태와 함께 호출한다는 것이다. 따라서 TodoPage가 가진 handleDelete라는 데이터가 TodoItem에서도 접근 가능하다(전체코드).

 

  Render Props에 대해 더 자세히 알고 싶다면 최근 작성한 Render Props에 대해 정리한 포스팅을 방문해보자.

 


context: https://reactjs.org/docs/context.html

render-props: https://reactjs.org/docs/render-props.html

todos 코드 : https://medium.com/@jeromefranco/how-to-avoid-prop-drilling-in-react-7e3a9f3c8674