[React Native] Context API를 적용해보자.

이지민·2024년 9월 2일
0

ReactNative

목록 보기
4/12

1.Context API란

React Native에서 Context API는 애플리케이션에서 전역적으로 데이터를 관리하고, 그 데이터를 여러 컴포넌트에 전달할 때 유용한 도구입니다. 이 API는 React에서 기본적으로 제공되며, Redux와 같은 상태 관리 라이브러리 없이도 전역 상태를 관리할 수 있도록 도와줍니다.

라고 한다.

이 라이브러리를 알게된게, 공모전 프로젝트인 Re-Dream을 진행하게 되면서 구현해야하는 screen의 갯수가 기하급수적으로 늘어나게 되었는데, 매 화면마다 관련 prop들을 route를 통해 일일히 전해줘야된다는게, 너무 불편했고, 전해졌는지 확인해야 하는것도 번거로웠다.

하지만 전역 상태 관리 라이브러리인 redux를 사용하자니, 전체 screen stack에서 하나의 기능을 담당하는 screen에만 필요한 prop들이라서 다른방법이 있나 찾아보다 알게 되었다!

2.사용방법

react에서 제공하는 기본 라이브러리이므로, 따로 설치는 하지 않아도 된다.

1. Context 생성

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

// Context 생성
const MyContext = createContext();

2. Provider 설정

const MyProvider = ({ children }) => {
  const [state, setState] = useState("Hello, Context!");

  return (
    <MyContext.Provider value={{ state, setState }}>
      {children}
    </MyContext.Provider>
  );
};

export default MyProvider;

이런식으로 사용해주면 된다.

3.예시

나의 screen 구조는 다음과 같다.

const RootStack = createNativeStackNavigator();
const SignUpStack = createNativeStackNavigator();
const CreateBookStack = createNativeStackNavigator();

function SignUpStackScreen(){
  return (
    <SignUpProvider>
      <SignUpStack.Navigator>
        <SignUpStack.Screen name="SignUp1" component={SignUpScreen1} options={{headerShown: false}} />
        <SignUpStack.Screen name="SignUp2" component={SignUpScreen2} options={{headerShown: false}} />
        <SignUpStack.Screen name="SignUp3" component={SignUpScreen3} options={{headerShown: false}} />
        <SignUpStack.Screen name="SignUp4" component={SignUpScreen4} options={{headerShown: false}} />
        <SignUpStack.Screen name="SignUp5" component={SignUpScreen5} options={{headerShown: false}} />
      </SignUpStack.Navigator>
    </SignUpProvider>
  )
}

function CreateBookStackScreen(){
  return (
    <CreateBookProvider>
      <CreateBookStack.Navigator>
        <CreateBookStack.Screen name="CreateBook1" component={CreateBookScreen1} options={{headerShown: false}}/>
        <CreateBookStack.Screen name="CreateBook2" component={CreateBookScreen2} options={{headerShown: false}}/>
        <CreateBookStack.Screen name="CreateBook3" component={CreateBookScreen3} options={{headerShown: false}}/>
        <CreateBookStack.Screen name="CreateBook4" component={CreateBookScreen4} options={{headerShown: false}}/>
        <CreateBookStack.Screen name="CreateSuccess" component={CreateSuccessScreen} options={{headerShown: false}}/>
        <CreateBookStack.Screen name="CreateFail" component={CreateFailScreen} options={{headerShown: false}}/>
      </CreateBookStack.Navigator>
    </CreateBookProvider>
  )
}

function App() {
  return (
    <Provider store={store}>
      <NavigationContainer>
        <RootStack.Navigator>
          <RootStack.Screen name="Login" component={LoginScreen} options={{ headerShown: false }} />
          <RootStack.Screen name="SignUp" component={SignUpStackScreen} options={{ headerShown: false }} />
          <RootStack.Screen name="Main" component={BottomTabNavigator} options={{ headerShown: false , animation: 'fade'}} />
          <RootStack.Screen name="CreateBook" component={CreateBookStackScreen} options={{headerShown: false}}/>
        </RootStack.Navigator>
      </NavigationContainer>
    </Provider>
  );
}

이런식으로 루트스택안에 하나의 기능을 담당하는 스택이 있고, createBookProvider 라는 context가 createBook이라는 기능에서 스크린간 공유가 필요한 변수를 관리하고 있다.

import React, { createContext, useState, useContext, ReactNode } from 'react';
import { useSelector } from 'react-redux'; // Redux 사용
import { RootState } from '../redux/store';

// Context의 타입 정의
interface BookData {
    user_id: string;
    title: string;
    genre: string;
    keyword: string[];
    description: string;
}

interface CreateBookContextType {
    bookData: BookData;
    setBookData: React.Dispatch<React.SetStateAction<BookData>>;
}

// Context 기본값 설정
const defaultContextValue: CreateBookContextType = {
    bookData: { user_id: '', title: '', genre: '', keyword: [], description: '' },
    setBookData: () => {}, // 기본값은 빈 함수
};

// Context 생성
const CreateBookContext = createContext<CreateBookContextType>(defaultContextValue);

// Custom hook for using context
export const useCreateBook = () => useContext(CreateBookContext);

// Context Provider 컴포넌트
export const CreateBookProvider: React.FC<{ children: ReactNode }> = ({ children }) => {
    const userId = useSelector((state: RootState) => state.auth.user?.id);

    if (!userId) {
        throw new Error("User is not logged in. User ID is required.");
    }

    const [bookData, setBookData] = useState<BookData>({
        title: '',
        genre: '',
        keyword: [],
        description: '',
        user_id: userId, // user_id 초기값 설정
    });

    return (
        <CreateBookContext.Provider value={{ bookData, setBookData }}>
            {children}
        </CreateBookContext.Provider>
    );
};

createBookContext이다. context생성시에 입력받을 bookData와 함수를 미리 넣어준다.

const { bookData, setBookData } = useCreateBook();

사용할때는 이런식으로 import해서 사용하면 된다.

해당 context는 provider로 감싸져 있는 화면스택에서만 제공되기 때문에, 다른 스택에 있는 화면에서는 이 context에 접근할 수 없다.

4.후기

아무것도 모르는 생초보인지라 공식문서를 봐도 이해가 안되서 gpt의 힘을 빌려가며 어떻게 구현이 되었다.

profile
개발자가 되고싶어요

0개의 댓글