리액트 네이티브 코드를 작성 중에 발생한 일이였습니다.
<Stack.Navigator
screenOptions={{
header: ({navigation, route, options}) => (
<Header title={options.title} /> // 모든 Stack 화면에 공통 헤더 적용
),
}}>
{loggedIn ? (
<>
<Stack.Screen name="Bottom" component={BottomTabScreen} />
<Stack.Screen name="Home" component={Home} />
>
) : (
<>
<Stack.Screen
name="Login"
component={Login}
options={{title: '로그인'}}
/>
<Stack.Screen
name="Join"
component={Join}
options={{title: '회원가입'}}
/>
>
)}
Stack.Navigator>
저는 몰랐던 사실이였는데 잘 보면
Stack.Navigator 안쪽에 헤더 옵션을 넣어주는 코드가 있는데 그 안에 컴포넌트를 바로 선언해 사용했습니다.
이렇게 된다면 do not define components during render 에러가 발생하는데,
React 에서는 컴포넌트 함수 내에서 다른 컴포넌트함수를 선언하는 것은 피해야 합니다
screenOptions={{
header: ({navigation, route, options}) => (
<Header title={options.title} /> // 모든 Stack 화면에 공통 헤더 적용
),
}}>
이 부분이 해당 에러인데
const header = (title)=>{
return <Header title={title} />;
}
<Stack.Navigator
screenOptions={{
header: ({navigation, route, options}) => (
header(options.title)
),
}}>
{loggedIn ? (
<>
<Stack.Screen name="Bottom" component={BottomTabScreen} />
<Stack.Screen name="Home" component={Home} />
>
) : (
<>
<Stack.Screen
name="Login"
component={Login}
options={{title: '로그인'}}
/>
<Stack.Screen
name="Join"
component={Join}
options={{title: '회원가입'}}
/>
>
)}
Stack.Navigator>
코드 예시를 든거라 문법적으로는 틀리나 코드처럼 해당 함수 내에 선언하는게 아니라 외부에 선언해 사용하는게 맞는 변수가 맞습니다
왜 이렇게 사용해야 하는지에 대한 이유가 중요했습니다.
컴포넌트 함수내에서 재정의 하면 해당 컴포넌트는 새로운 컴포넌트로 인식해 하위 트리의 모든 값들을 재설정 하게 됩니다. 쉽게 말해서 모두 초기화 된다는 점 입니다.
매번 새롭게 재정의 되고 초기화된다면 그것 자체가 비효율 적인 리랜더링이니 반드시 피해야 합니다.
아래 모범예시 코드를 보며 글 마치겠습니다.
const NestedComponent = () => {
return <div>Nested Componentdiv>;
};
const MyComponent = () => {
return (
<div>
<h1>Main Componenth1>
<NestedComponent /> {/* 이제는 매 렌더링 시 재정의되지 않음 */}
div>
);
};