React의 데이터 흐름은 "단방향(One Way) 하향식"입니다. 위에서 아래로 props를 전달하고, 아래에서 callback 을 실행해 전달 받은 상태를 업데이트 합니다. 문제는 컴포넌트 트리가 복잡해지면 상태 관리가 매우 어려워집니다.
뿐만 아니라, props를 아래 방향으로 한 단계씩 전달 ▸ 전달 해야 하기 때문에 불필요하게 중간에서 전달 받아 다시 아래 방향으로 전달하는 경우도 빈번하게 발생하게 됩니다.
문제 상황을 이해하기 위해 다음의 예시 코드를 살펴봅니다. Z, A, B는 각각 App, MenuBar, SignIn 컴포넌트입니다.
// Z(App)가 인증 정보를 B(SignIn)에게 전달하기 위해// A(MenuBar)에게 인증 정보를 전달 함.classAppextendsReact.Component { state = { authentification:true }render() {return ( <divclassName="app"> <MenuBarisAuth={this.state.authentification} /> {/* ... */} </div> ) }}// A(MenuBar)는 인증 정보가 필요 없지만,// B(SignIn)에게 전달해야 함.constMenuBar= props => ( <divclassName="menubar"> <SignInisAuth={props.isAuth} /> {/* ... */} </div>)// A(MenuBar)를 거쳐 Z(App)가 전달한 // 인증 정보를 힘겹게 받은 B(SignIn)constSignIn= props => {constsigned=props.isAuthif (signed) {return <divclassName="signed">로그인 사용자</div> } else {return <divclassName="un-signed">로그인 되지 않음</div> }}
컨텍스트(Context) 활용
React는 복잡한 컴포넌트 트리의 "상태 공유 문제를 해결하기 위한 방법"으로 컨텍스트(Context) API를 제공합니다. Context API를 사용하면 상위 컴포넌트에서 하위에 종속된 모든 컴포넌트에 데이터를 공급(Provider)한 후, 특정 위치의 컴포넌트에서 바로 수요(Consumer) 하도록 설정할 수 있습니다.
Context를 통한 데이터 "공급", "수요"의 의미가 아직은 모호하게 느껴질 수 있습니다. 아래 예시 코드를 살펴보면 그 모호함이 다소 해소될 수 있을 것입니다.
// 컨텍스트 생성.constAuthContext=React.createContext();// -------------------------------------------------------------classAppextendsReact.Component { state = { authentification:true }render() {// AuthContext.Provider 요소를 사용해 // 인증 정보를 값(value)으로 공급constvalue= { ...this.state }return ( <divclassName="app"> <AuthContext.Providervalue={value}> <MenuBar /> {/* ... */} </AuthContext.Provider> </div> ) }}constMenuBar= () => ( <divclassName="menubar"> <SignInisAuth={props.isAuth} /> {/* ... */} </div>)// AuthContext.Consumer를 통해 전달 받은 // 값(value)을 사용해 렌더링.constSignIn= () => ( <AuthContext.Consumer> { (context) => context ? <divclassName="signed">로그인 사용자</div> : <divclassName="un-signed">로그인 되지 않음</div> } </AuthContext.Consumer>)
Context의 주된 사용 목적은 복잡하게 "중첩 된" 하위 컴포넌트(들)에 데이터를 공유하는 것입니다. Context를 사용하면 컴포넌트 재사용이 어려우므로 꼭 필요한 경우에만 사용합니다. (참고)