[React Native] 컴포넌트 이해 - functional componenet 외부에서 state 호출할 수 없는 경우
Nadan Dev Blog
개요
블로그 혹은 커뮤니티 앱을 만들 때, 디테일 화면에서 ‘편집’ 버튼이 헤더에 들어가는 경우가 있다. 이 경우 헤더 아이콘의 onPress 함수에서 state 값을 변경해 줘야 하는데 만약 react native에서 제공해주는 default 헤더를 사용하고 있다면 navigationOptions에 onPress 설정해 줘야 한다.
문제는 이렇게 할 경우 navigationOptions에서 state를 호출할 수 없다는 오류가 생긴다. 정확하게는 component function 밖에서는 hook을 호출할 수 없다는 오류이다. 가장 쉬운 해결 방법은 custom 헤더를 만드는 것인데, 헤더에 복잡한 기능이 들어가는 것이 아니기 때문에 직접 그리는 것이 가장 좋은 선택일 것이다. 만약 꼭 default 헤더를 사용해야 한다면 navigationOptions의 argument를 통해 전달되는 navigation을 통해 param을 전달할 수 있다.
오류 상황
ShowScreen.navigationOptions = () => {
const { state, setEditable } = useContext(BlogContext);
const { editable } = state;
const [editable, setEditable] = useState(false);
return {
headerRight: () => (
<TouchableOpacity onPress={() => setEditable(!editable)}>
<Feather name="edit-2" size={24} color="black" />
</TouchableOpacity>
),
headerRightContainerStyle: {
paddingHorizontal: 10,
},
title: "Show",
headerBackTitle: "",
};
};
navigation을 통해 param 전달
param로 object를 전달할 수 있기 때문에 state 값과 이를 변경할 수 있는 함수를 넘겨준다.
const ShowScreen = ({ navigation }) => {
...
useEffect(() => {
const setEditableWrapper = () => {
setEditable(!editable);
}
navigation.setParams({ setEditableWrapper, editable });
}, [editable]);
...
};
ShowScreen.navigationOptions = ({ navigation }) => {
const setEditable = navigation.getParam('setEditableWrapper');
const editable = navigation.getParam('editable');
return {
headerRight: () => (
<TouchableOpacity
onPress={() => setEditable()}
activeOpacity={1}>
{ !editable ? <Feather name="edit-2" size={24} color="black" /> : null }
</TouchableOpacity>
),
headerRightContainerStyle: {
paddingHorizontal: 10
},
title: 'Show',
headerBackTitle: ''
};
};