본문 바로가기

모바일 개발/React Native-이론

Header Button 달기

Header buttons | React Navigation

(1) Screen Component의 옵션 이용해서 헤더 버튼 달기 

스크린 컴포넌트의 Options에서 headerRight, headerLeft key 값에다가 
함수형 컴포넌트를 value로 기입한다. 
그러면 해당 함수형 컴포넌트의 로직 대로 움직인다. 

우리는 해당 함수형 컴포넌트가 <Button/> 태그를 반환하도록 만들었다. 
<View></View>를 따로 쓰지 않아도 돌아가는 것 보니, 
저번 설명에서 처럼 Screen의 Header 전체를 감싸는 View 태그가 내장되어 
있는 것 같다. 

function StackScreen() {
  return (
    <Stack.Navigator>
      <Stack.Screen
        name="Home"
        component={HomeScreen}
        options={{
          headerTitle: (props) => <LogoTitle {...props} />,
          headerRight: () => (
            <Button
              onPress={() => alert('This is a button!')}
              title="Info"
              color="#fff"
            />
          ),
        }}
      />
    </Stack.Navigator>
  );
}

밑에 처럼 Options에서 콜백함수를 이용해, route를 받아서 option value 컴포넌트의 인수로도 보낼 수 있다.

        options={({route}) =>({
          headerTitle: ({route.param}) => <LogoTitle {...props} />,
          headerRight: () => (
            <Button
              onPress={() => alert('This is a button!')}
              title="Info"
              color="#fff"
            />
          ),
        })}

하지만 이렇게 스크린 컴포넌트의 옵션으로 헤더 버튼을 만드는 것은 
안 좋은 방법이다. 
왜냐하면 
헤더는 스크린의 내용물이 되는 컴포넌트와 완전히 관계 없는 부분이기 때문에, 
헤더의 버튼을 누름으로서 해당 헤더가 속한 스크린과 상호작용을 할 수 없다.
(제 3의 컴포넌트에 상태 변수를 보내고, 이를 통해 헤더 컴포넌트와 스크린을
연결하는 작업으로 가능하게 할 수 있지만 너무 번거롭다.)

(2) 옵션을 통해 만든 헤더와 스크린(내용물) 간의 상호 작용

function StackScreen() {
  return (
    <Stack.Navigator>
      <Stack.Screen
        name="Home"
        component={HomeScreen}
        options={({ navigation, route }) => ({
          headerTitle: (props) => <LogoTitle {...props} />,
          /*버튼 이름만 있을 뿐 기능이 없음*/
          headerRight: () => (
            <Button title="Update count" />
          ),
        })}
      />
    </Stack.Navigator>
  );
}

function HomeScreen({ navigation }) {
  const [count, setCount] = useState(0);

/*navigation에 변동사항이 생기면, 즉 화면이동을 하면 해당 setOptions가 발동함
	어떠한 곳으로라도, 화면 이동시 header의 버튼에 기능이 생김*/
  useEffect(() => {
    navigation.setOptions({
      headerRight: () => (
        <Button onPress={() => setCount((c) => c + 1)} title="Update count" />
      ),
    });
  }, [navigation]);

  return <Text>Count: {count}</Text>;
}

(3) back 버튼 커스터마이징 하기 

a. back 버튼의 이름이나 이미지, 텍스트 스타일만 바꾸기 

headerBackTitleStyle이나 , headerBackTitle 같은 options의 key값의 value를 채워넣음으로서 가능 

BactTitle 사용 시 주의점. 

해당 속성은 이 속성을 쓴 스크린에 적용되는 것이 아니라, 화면 이동한 다음 스크린의 back 버튼으로 적용된다. 

headerBackTitle props not working · Issue #1358 · react-navigation/react-navigation · GitHub

b. 아예 back 버튼 커스터마이징 해버리기 

위에서 배운 HeaderLeft에 콜백함수를 넣어서 완전히 커스터마이징 해버리면 된다. 

back 버튼은 default 값으로 우리가 HeaderLeft를 커스터 마이징 시 우선순위에서 밀려나 사라진다.