My Boundary As Much As I Experienced

RN) 맨날 하는 고민... 헤더와 스크린 간의 데이터 전달을 어떻게 할까? (navigation.setOptions) 본문

FrontEnd/React Native

RN) 맨날 하는 고민... 헤더와 스크린 간의 데이터 전달을 어떻게 할까? (navigation.setOptions)

Bumang 2024. 8. 22. 20:37

문제 상황

만약 리액트네비게이션을 라우터로 사용하면

실제 Screen과 header는 App.tsx에서 분리되어 사용되고 있을 것이다. 아래처럼.

      <BottomTab.Screen
        name="Home"
        component={Home} // 스크린 컴포넌트
        options={{
          tabBarLabel: "홈",
          header: () => <CustomHeader type="HOME" />, // 헤더 컴포넌트
        }}
      />

 

그런데 어떤 스크린에서는 스크린 내의 상태에 따라 헤더의 상태도 변하게 해야될 때가 있다.

이럴 경우에 어떻게 조작해야되나? 이들의 공통 상위컴포넌트인 App.tsx에 state들을 위치시켜야할까?

좋은 방법은 아닐 것이다. 그렇게 거추장스럽게 App.tsx에 상태들을 많이 만들어서 props drilling시키는건 좋지 않다..

 

이때 몇 가지 방법이 대표적으로 떠오르는데 바로,

- 1.  React Context

- 2. 전역상태관리 라이브러리

- 3. navigation.setOptions

이다.

 

navigation.setOptions(...)로 헤더 설정하기

이중 별도의 설정 없이 React Navigation의 기능 중 하나인 setOptions로 헤더값을 바꾸는 예시를 보여주겠다.

아래 코드는 어떤 스크린에 들어오면 navigation의 setOptions를 통해 title, style, tint, ... 헤더 옵션들을 바꿔준다.

useEffect를 통해서 어떤 상태가 바뀔때마다 계속 실행시킬수도 있고 핸들러를 통해 변경하는 것도 물론 가능하다.

import { useEffect } from 'react';
import { useNavigation } from '@react-navigation/native';

function MyScreen() {
  const navigation = useNavigation();

  useEffect(() => {
    navigation.setOptions({
      headerTitle: 'My Custom Header',
      headerStyle: {
        backgroundColor: '#f4511e',
      },
      headerTintColor: '#fff',
      headerTitleStyle: {
        fontWeight: 'bold',
      },
    });
  }, []);

  return (
    // Your screen content
  );
}

 

 

실제 내가 사용하는 방식

나는 커스텀 헤더 컴포넌트를 쓰는 중이라, 위처럼 headerStyle, headerTitle... 등을 쓸 수 없었다.

나는 header 속성에 실제 내가 쓰는 커스텀 헤더의 jsx를 주입하는 방식으로 헤더를 쓰고 있었기 때문에,

setOptions에서도 똑같이 header속성에 jsx를 집어넣되, 내가 원하는 값도 포함시켜서 주입했다.

import { useEffect } from 'react';
import { useNavigation } from '@react-navigation/native';

function MyScreen() {
  const navigation = useNavigation();

  useEffect(() => {
    navigation.setOptions(
        // 나는 커스텀 헤더를 따로 만들어 이렇게 사용하고 있는데, useEffect를 통해 sideEffect에 따라 prop을 내가 원하는 대로 바꿔준다.
    	header: () => <CustomHeader type="HOME" 내가원하는값={내가원하는값} />,
    );
  }, []);

  return (
    // Your screen content
  );