리액트 훅이 도입된 리액트 16.8부터는 context를 사용하는 다른 방법이 등장했습니다.

이제는 useContext훅을 사용해 context를 사용할 수 있다.

render props를 사용하는 대신 context를 사용할 때 컴포넌트 최상단에 React.useContext()에 전체 context객체를 내려줄 수 있다.

import React from 'react';
export const UserContext = React.createContext();
export default function App() {
  return (
    <UserContext.Provider value="Reed">
      <User />
    </UserContext.Provider>
  )
}
function User() {
  const value = React.useContext(UserContext);  
    
  return <h1>{value}</h1>;
}

useContext를 사용하면 Render Props에 비하면 훨씬 깔끔하게 사용할 수 있다.

Context에서 유동적인 값 다루기

APP컴포넌트에서 useState를 사용해 관리하는 상태를 Provider로 넣어주면 값이 바뀔때 useContext를 사용하는 컴포넌트 쪽에서도 리렌더링이 잘 발생할 것이다.

Provider를 사용하는 컴포넌트에서 Context의 상태를 관리하는 것보다는 Provider전용 컴포넌트를 따로 만드는 것이 유지보수성이 더 높다. 특히 Context에서 다루는 로직이 복잡할 때는 전용 컴포넌트를 만드는 것이 좋다.

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

const LogContext = createContext();

export function LogContextProvider({children}) {
  const [text, setText] = useState('');
  return (
    <LogContext.Provider value={{text, setText}}>
      {children}
    </LogContext.Provider>
  )
}

export default LogContext;

내부에서는 useState를 사용해 간단한 문자열 상태 값을 관리하고, Provider의 value에는 text와 setText를 넣어줬다.

import React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { LogContextProvider } from './contexts/LogContext';
import RootStack from './screens/RootStack';

function App() {
  return (
    <NavigationContainer>
      <LogContextProvider>
        <RootStack />
      </LogContextProvider>
    </NavigationContainer>
  );
}

export default App;

LogContextProvider라는 컴포넌트 안에 FeedsScreen 컴포넌트를 넣어주면 RootStack 컴포넌트 안에서 useState로 선언된 text와 setText를 Context 통해서 공유할 수 있다.

RootStack 안에는 FeedsScreen, CalendarScreen 컴포넌트가 존재한다.