ABOUT ME

jacey.park.dev@gmail.com \n 5년차 프론트엔드 개발자

Today
-
Yesterday
-
Total
-
  • [JS] React.js Context API 알아보기
    Dev/JS 2018. 6. 3. 15:46

    Context


     일반적인 React 어플리케이션에서 데이터들은 prop를 통해 하향식(부모 -> 자식) 으로 전달이 됩니다. 하지만,

    어플리케이션 내에 많은 컴포넌트들이 특정 타입의 props(예를 들어 locale 설정, ui 테마) 를 받기 위해서는 좀 번거로울 수 있습니다.

    그래서 Context 는 트리 레벨을 통해 prop를 전달하지 않으면서 컴포넌트 끼리 값을 공유하는 방법을 제공합니다.





    Context를 언제 사용하느냐?


     Context는 현재 인증된 사용자, 테마, 또는 기본 설정 언어와 같은 React 의 여러 컴포넌트에 대해서 '전역' 으로 

    여겨질 수 있는 데이터들을 공유하도록 설계되었습니다.  예를 들어 아래 코드에서는 Button 컴포넌트의 스타일을

    지정하기 위해 'Theme' props를 수동으로 전달합니다



    class App extends React.Component {
    render() {
    return <Toolbar theme="dark" />;
    }
    }


    function Toolbar(props) {
    // 툴바 컴포넌트는 무조건 "theme" props를 가져야 합니다.
    // 그리고 이것을 ThemeButton로 전달해야 합니다.
    // 만약, 앱에 있는 모든 single 버튼들이 테마를 가져야 할때는 정말 번거롭겠죠?
    // 왜냐! 그것을 하기 위해서는 모든 컴포넌트들을 거쳐야 하기 때문이죠
    return (
    <div>
    <ThemedButton theme={props.theme} />
    </div>
    );
    }


    function ThemedButton(props) {
    return <Button theme={props.theme} />;
    }



    컨텍스트를 사용하면, 중간 컴포넌트를 거치지 않고 prop를 전달할 수 있습니다.



    // 컨텍스트는 깊숙히 있는 컴포넌트 트리를 통해서 값을 보낼 수 있게 합니다.
    // 모든 컴포넌트들을 거치는 번거로운 작업 없이 말이죠.
    // 현재 테마를 위한 컨텍스트를 만들어 보겠습니다. ("light" 라는 default 테마를 사용해서요)
    const ThemeContext = React.createContext('light');


    class App extends React.Component {
    render() {
    // Provider를 사용하여 현재 테마를 트리 아래에다 전달합니다.
    // 다른 컴포넌트들은 테마가 얼마나 깊은곳에 위치했냐 안했냐 몰라도 그냥 읽을 수 있습니다.
    // 이 예제에서는, 우리는 "dark" 테마를 현재 값으로 보낼 것 입니다.
    return (
    <ThemeContext.Provider value="dark">
    <Toolbar />
    </ThemeContext.Provider>
    );
    }
    }


    // 중간에 있는 컴포넌트들은 테마를 하향식으로 더이상
    // 보내지 않아도 됩니다.
    function Toolbar(props) {
    return (
    <div>
    <ThemedButton />
    </div>
    );
    }


    function ThemedButton(props) {
    // 이제 Consumer를 통해서 현재 테마의 값을 테마 컨텍스트로 읽을 수 있습니다.
    // React가 가까운 테마 Provider를 찾아서 그 값을 사용할 수 있게 해줍니다.
    // 이 예제 에서의 현재 테마는 "dark" 입니다.
    return (
    <ThemeContext.Consumer>
    {theme => <Button {...props} theme={theme} />}
    </ThemeContext.Consumer>
    );
    }



    참고 : props가 많은 단계 아래로 통과되는 것이 아니면 Context 를 사용하지 마세요!




    API - React.createContext



    const {Provider, Consumer} = React.createContext(defaultValue);


    { Provider, Consumer } 짝을 만듭니다. 그리고 React가 Consumer 컨텍스트를 렌더링하면, Consumer 와 가장 가까운 Provider 위에 

    일치하는 컨텍스트 값을 읽어옵니다.


    그리고 인수로 넣어준 defaultValue 는 트리에서 일치하는 Provider가 없는 경우에만 Consumer가 사용하게끔 되어있습니다.

    이는 컴포넌트를 개별적으로 테스트 할 때 유용합니다. 


    참고 : undefined Provider 값을 전달한다고 해서 Consumer가 defaultValue를 사용하는 것은 아닙니다.


    API - Provider



    <Provider value= { /* some code here */}>


    Consumer 가 Context의 변경사항을 가져올 수 있게 하는 React Component 입니다.


    value는 Provider가 Consumer에게 전달할 props 가 들어갈 자리입니다. 이때 하나의 Provider는

    많은 Consumer들과 연결될 수 있습니다. 또한, Provider를 여러개 중첩하여 트리 내에서 더 깊은 값을 무시할 수 도 있습니다.




    API - Consumer



    <Consumer>
    {value => /* 컨텍스트 값이 렌더링됩니다. */}
    </Consumer>


    Consumer는 Context의 변경사항을 읽을 수 있는 컴포넌트 입니다.

    이때 자식 컴포넌트로서의 기능이 필요합니다. 이 함수는 현재 Context 값을 받고 React 노드를 반환하고 있습니다. 
    value 함수에 전달된 인수는 트리에서 이 컨텍스트에 대해서 가장 가까운 Provider의 props와 같습니다. 

    위의 컨텍스트에 대한 Provider가 없는 경우, value 인수는 위의 createContext 에서 전달된 defaultValue 와 같습니다. 


    댓글

Designed by Tistory.