리포는 https://github.com/react-navigation/react-navigation/tree/main/packages/react-native-tab-view로 옮겨졌습니다. 문제를 열고 요청을 가져 오십시오.
React Native의 크로스 플랫폼 탭보기 구성 요소. Android & IOS에서 react-native-pager-view 및 Web, MacOS 및 Windows에서 PanResponder를 사용하여 구현되었습니다.
이 라이브러리를 사용하려면 올바른 버전의 React Native를 사용해야합니다. 0.63 보다 낮은 React Native 버전을 사용하는 경우이 라이브러리를 사용하기 전에 업그레이드해야합니다.
react-native-tab-view 버전 | 필요한 반응 기본 버전 |
|---|---|
2.xx | < 0.63 |
3.xx | >= 0.63 |
프로젝트 루트에서 터미널을 열고 실행하십시오.
yarn add react-native-tab-view 이제 iOS 및 Android를 지원하려는 경우 react-native-pager-view 설치해야합니다.
엑스포를 사용하는 경우 라이브러리의 호환 버전을 얻으려면 실행하십시오.
expo install react-native-pager-view엑스포를 사용하지 않는 경우 다음을 실행하십시오.
yarn add react-native-pager-view우리는 끝났어! 이제 장치/시뮬레이터에서 앱을 빌드하고 실행할 수 있습니다.
import * as React from 'react' ;
import { View , useWindowDimensions } from 'react-native' ;
import { TabView , SceneMap } from 'react-native-tab-view' ;
const FirstRoute = ( ) => (
< View style = { { flex : 1 , backgroundColor : '#ff4081' } } />
) ;
const SecondRoute = ( ) => (
< View style = { { flex : 1 , backgroundColor : '#673ab7' } } />
) ;
const renderScene = SceneMap ( {
first : FirstRoute ,
second : SecondRoute ,
} ) ;
export default function TabViewExample ( ) {
const layout = useWindowDimensions ( ) ;
const [ index , setIndex ] = React . useState ( 0 ) ;
const [ routes ] = React . useState ( [
{ key : 'first' , title : 'First' } ,
{ key : 'second' , title : 'Second' } ,
] ) ;
return (
< TabView
navigationState = { { index , routes } }
renderScene = { renderScene }
onIndexChange = { setIndex }
initialLayout = { { width : layout . width } }
/>
) ;
}간식 에서이 예제를 사용해보십시오
패키지는 탭보기를 렌더링하는 데 사용하는 TabView 구성 요소와 기본 탭 막대 구현 인 TabBar 구성 요소를 내 보냅니다.
TabView탭 탭 및 관리를 담당하는 컨테이너 구성 요소. 기본적으로 재료 설계 스타일을 따릅니다.
기본 사용법은 다음과 같습니다.
< TabView
navigationState = { { index , routes } }
onIndexChange = { setIndex }
renderScene = { SceneMap ( {
first : FirstRoute ,
second : SecondRoute ,
} ) }
/> navigationState ( required )탭보기의 상태. 주에는 다음 속성이 포함되어야합니다.
index : routes 배열에서 활성 경로의 인덱스를 나타내는 숫자routes : 탭 렌더링에 사용되는 경로 개체 목록이 포함 된 배열각 경로 개체에는 다음 속성이 포함되어야합니다.
key : 경로를 식별하기위한 고유 키 (필수)title : 탭 바에 표시되는 경로에 대한 제목icon : 탭 막대에 표시되는 경로의 아이콘accessibilityLabel : 탭 버튼의 접근성 레이블testID : 탭 버튼의 테스트 ID예:
{
index : 1 ,
routes : [
{ key : 'music' , title : 'Music' } ,
{ key : 'albums' , title : 'Albums' } ,
{ key : 'recents' , title : 'Recents' } ,
{ key : 'purchased' , title : 'Purchased' } ,
]
} TabView 제어 된 구성 요소이며, 이는 onIndexChange 콜백을 통해 index 업데이트해야 함을 의미합니다.
onIndexChange ( required )탭 변경에서 호출되는 콜백은 인수로 새 탭의 색인을 수신합니다. 내비게이션 상태는 호출되면 업데이트되어야합니다. 그렇지 않으면 변경 사항이 삭제됩니다.
renderScene ( required )반응 요소를 반환하여 탭의 페이지로 렌더링하는 콜백. 경로를 포함하는 객체를 인수로받습니다.
const renderScene = ( { route , jumpTo } ) => {
switch ( route . key ) {
case 'music' :
return < MusicRoute jumpTo = { jumpTo } /> ;
case 'albums' :
return < AlbumsRoute jumpTo = { jumpTo } /> ;
}
} ; 개별 경로가 성능을 향상시키기 위해 꼭 봐야 shouldComponentUpdate 구현해야합니다. 구성 요소를보다 쉽게 지정할 수 있도록 SceneMap 도우미를 사용할 수 있습니다.
SceneMap route.key 를 매핑하여 객체를 사용하여 구성 요소를 반응하고 renderScene 소품과 함께 사용할 함수를 반환합니다.
import { SceneMap } from 'react-native-tab-view' ;
...
const renderScene = SceneMap ( {
music : MusicRoute ,
albums : AlbumsRoute ,
} ) ; 이러한 방식으로 구성 요소를 지정하는 것이 더 쉽고 shouldComponentUpdate 메소드를 구현해야합니다.
각 장면은 다음 소품을받습니다.
route : 구성 요소가 렌더링 한 현재 경로jumpTo : 다른 탭으로 점프하는 메소드, route.key 가 인수대로 가져옵니다.position : 현재 위치를 나타내는 애니메이션 노드 jumpTo 방법은 프로그래밍 방식으로 다른 탭으로 이동하는 데 사용될 수 있습니다.
this . props . jumpTo ( 'albums' ) ; SceneMap 으로 렌더링 된 모든 장면은 React.PureComponent 사용하여 최적화되며 부모의 소품이나 상태가 변경 될 때 다시 렌더링하지 않습니다. 장면 업데이트 방법을 더 많이 제어 해야하는 경우 (예 : navigationState 변경되지 않은 경우에도 재 러너 트리거) SceneMap 사용하는 대신 renderScene 직접 사용하십시오.
중요 : 예를 들어, SceneMap 함수를 전달 하지 마십시오 . 예를 들어 다음을 수행하지 마십시오.
SceneMap ( {
first : ( ) => < FirstRoute foo = { this . props . foo } /> ,
second : SecondRoute ,
} ) ;파일의 최상위 레벨의 다른 곳에서 항상 구성 요소를 정의하십시오. 인라인 함수를 전달하면 모든 렌더마다 구성 요소를 다시 만들어 내면 전체 경로가 마운트를 마치고 모든 변경 사항을 다시 마운트하게합니다. 성능은 매우 나쁘고 모든 지역 상태를 잃게됩니다.
추가 소품을 전달 해야하는 경우 사용자 정의 renderScene 함수를 사용하십시오.
const renderScene = ( { route } ) => {
switch ( route . key ) {
case 'first' :
return < FirstRoute foo = { this . props . foo } /> ;
case 'second' :
return < SecondRoute /> ;
default :
return null ;
}
} ; renderTabBar탭 막대로 사용하기 위해 사용자 정의 반응 요소를 반환하는 콜백 :
import { TabBar } from 'react-native-tab-view' ;
...
< TabView
renderTabBar = { props => < TabBar { ... props } /> }
. . .
/ >이것이 지정되지 않으면 기본 탭 막대가 렌더링됩니다. 이 소품을 전달하여 기본 탭 막대를 사용자 정의하거나 탭 막대를 제공하거나 탭 막대를 완전히 비활성화합니다.
< TabView
renderTabBar = { ( ) => null }
. . .
/ > tabBarPosition 탭보기에서 탭 막대의 위치. 가능한 값은 'top' 과 'bottom' 입니다. 기본값은 'top' 입니다.
lazy현재 경로가있는 객체를 취하고 부울을 반환하여 장면을 게으르게 렌더링할지 여부를 나타냅니다.
기본적으로 모든 장면은 매끄러운 스 와이프 경험을 제공하기 위해 렌더링됩니다. 그러나 사용자가 볼 때까지 초점이 맞지 않은 장면의 렌더링을 연기하고 싶을 수도 있습니다. 특정 장면에 대한 게으른 렌더링을 가능하게하려면 해당 route 의 getLazy 에서 true 반환하십시오.
< TabView
lazy = { ( { route } ) => route . name === 'Albums' }
. . .
/ > 화면에 게으른 렌더링을 활성화하면 일반적으로 초점을 맞출 때 렌더링하는 데 시간이 걸립니다. renderLazyPlaceholder Prop를 사용 하여이 짧은 기간 동안 사용자가 보는 내용을 사용자 정의 할 수 있습니다.
부울을 통과하여 모든 장면에 게으른 다음을 가능하게 할 수도 있습니다.
< TabView
lazy
/> lazyPreloadDistance lazy 활성화되면이 소품으로 얼마나 많은 인접한 경로를 사전로드 해야하는지 지정할 수 있습니다. 이 값은 기본값이 0으로 0 으로 표시되므로 게으른 페이지가 뷰포트에 들어올 때로드됩니다.
renderLazyPlaceholder 사용자 정의 반응 요소를 반환하는 콜백 아직 렌더링되지 않은 경로를 렌더링합니다. 경로를 포함하는 객체를 인수로받습니다. lazy 소품도 활성화되어야합니다.
이보기는 일반적으로 분할 초만 표시됩니다. 가볍게 유지하십시오.
기본적으로 이것은 null 을 렌더링합니다.
keyboardDismissMode드래그 제스처에 대한 응답으로 키보드가 해산되는지 여부를 나타냅니다. 가능한 값은 다음과 같습니다.
'auto' (기본값) : 인덱스가 변경되면 키보드가 기각됩니다.'on-drag' : 드래그가 시작되면 키보드가 기각됩니다.'none' : 드래그는 키보드를 해제하지 않습니다. swipeEnabled 스 와이프 제스처를 활성화할지 여부를 나타내는 부울. 스 와이프 제스처는 기본적으로 활성화됩니다. false 전달하면 스 와이프 제스처가 비활성화되지만 사용자는 탭 막대를 눌러 탭을 계속 전환 할 수 있습니다.
animationEnabled탭을 변경할 때 애니메이션을 활성화합니다. 기본적으로 그것은 사실입니다.
onSwipeStart스 와이프 제스처가 시작될 때 호출되는 콜백, 즉 사용자는 화면에 닿아 이동합니다.
onSwipeEnd스 와이프 제스처가 끝나면 호출되는 콜백, 즉 스 와이프 제스처 후에 사용자가 화면에서 손가락을 들어 올립니다.
initialLayout화면의 초기 높이와 너비를 포함하는 물체. 이를 통과하면 초기 렌더링 성능이 향상됩니다. 대부분의 앱의 경우 이것은 좋은 기본값입니다.
< TabView
initialLayout = { { width : Dimensions . get ( 'window' ) . width } }
. . .
/ > sceneContainerStyle각 화면 랩핑보기에 적용 할 수 있습니다. 오버플로 클리핑과 같은 일부 기본 스타일을 무시하기 위해 이것을 전달할 수 있습니다.
pagerStyle호출기 뷰에 적용하는 스타일 모든 장면을 감싸십시오.
style탭보기 컨테이너에 적용 할 스타일.
TabBar 재료 디자인 테마 탭 바. 탭 막대를 사용자 정의하려면 TabView 의 renderTabBar 바 소품을 사용하여 TabBar 렌더링하고 추가 소품을 전달해야합니다.
예를 들어, 표시기 색상과 탭 막대 indicatorStyle 색상을 사용자 정의하려면 각각 TabBar style 할 수 있습니다.
const renderTabBar = props => (
< TabBar
{ ... props }
indicatorStyle = { { backgroundColor : 'white' } }
style = { { backgroundColor : 'pink' } }
/>
) ;
//...
return (
< TabView
renderTabBar = { renderTabBar }
. . .
/ >
);getLabelText 현재 경로가있는 객체를 취하고 탭의 레이블 텍스트를 반환하는 함수. 기본적으로 route.title 사용합니다.
< TabBar
getLabelText = { ( { route } ) => route . title }
. . .
/ > getAccessible 현재 경로가있는 객체를 취하고 부울을 반환하여 탭을 accessible 것으로 표시할지 여부를 표시하는 함수. 기본값은 true .
getAccessibilityLabel 현재 경로가있는 객체를 취하고 탭 버튼의 접근성 레이블을 반환하는 함수. route.accessibilityLabel 기본적으로 사용하십시오. 지정된 경우 기본적으로 Route 제목을 사용합니다.
< TabBar
getAccessibilityLabel = { ( { route } ) => route . accessibilityLabel }
. . .
/ > getTestID 현재 경로가있는 객체를 가져 와서 탭 버튼의 테스트 ID를 반환하여 테스트 에서이 탭 버튼을 찾습니다. 기본적으로 route.testID 사용합니다.
< TabBar
getTestID = { ( { route } ) => route . testID }
. . .
/ > renderIcon현재 경로, 집중 상태 및 색상을 가진 객체를 취하고 아이콘으로 사용할 사용자 정의 반응 요소를 반환합니다.
< TabBar
renderIcon = { ( { route , focused , color } ) => (
< Icon
name = { focused ? 'albums' : 'albums-outlined' }
color = { color }
/>
) }
. . .
/ > renderLabel현재 경로, 집중 상태 및 색상을 가진 객체를 취하고 레이블로 사용할 사용자 정의 반응 요소를 반환하는 함수.
< TabBar
renderLabel = { ( { route , focused , color } ) => (
< Text style = { { color , margin : 8 } } >
{ route . title }
</ Text >
) }
. . .
/ > renderTabBarItem TabBarItemProps 객체를 사용하고 탭 버튼으로 사용할 사용자 정의 반응 요소를 반환하는 함수.
renderIndicator현재 경로가있는 객체를 취하고 탭 표시기로 사용할 사용자 정의 반응 요소를 반환하는 함수.
renderBadge현재 경로가있는 객체를 취하고 배지로 사용할 사용자 정의 반응 요소를 반환하는 함수.
onTabPress탭에서 실행할 함수를 누릅니다. 스크롤과 같은 것들에 유용한 눌린 탭의 장면을 수신합니다.
기본적으로 Tab Press는 탭도 전환합니다. 이 동작을 방지하기 위해 preventDefault 로 전화 할 수 있습니다.
< TabBar
onTabPress = { ( { route , preventDefault } ) => {
if ( route . key === 'home' ) {
preventDefault ( ) ;
// Do something else
}
} }
. . .
/ > onTabLongPress탭에서 실행하는 기능 Long Press, 더 많은 옵션이있는 메뉴를 보여주는 것과 같은 사용
activeColor활성 탭의 아이콘 및 레이블에 대한 사용자 정의 색상.
inactiveColor비활성 탭의 아이콘 및 레이블에 대한 사용자 정의 색상.
pressColor재료 리플의 색상 (Android> = 5.0 만 해당).
pressOpacity압축 탭의 불투명 (iOS 및 Android <5.0 만 해당).
scrollEnabled부울 탭 막대를 스크롤 할 수 있는지 여부를 나타냅니다.
scrollEnabled true 로 설정하면 초기 렌더를 개선하기 위해 tabStyle 의 width 지정해야합니다.
bounces부울 스크롤시 탭 바가 튀는 지 여부를 나타냅니다.
tabStyle탭 막대의 개별 탭 항목에 적용 할 스타일.
기본적으로 모든 탭 항목은 컨테이너 폭에 따라 동일한 사전 계산 너비를 차지합니다. 원래 너비를 가져 가려면 tabStyle 의 width: 'auto' 지정할 수 있습니다.
indicatorStyle활성 표시기에 적용 할 스타일.
indicatorContainerStyle표시기의 컨테이너보기에 적용 할 스타일.
labelStyle탭 항목 레이블에 적용 할 스타일.
contentContainerStyle탭의 내부 컨테이너에 적용 할 스타일.
style탭 바 컨테이너에 적용 할 스타일.
gap탭 사이의 간격을 정의합니다.
testID탭 바에 대한 테스트 ID. 테스트에서 탭 막대를 스크롤하는 데 사용할 수 있습니다.
탭보기를 React Navigation의 내비게이션 시스템과 통합하려면 navigation.navigate 등을 사용하여 탭으로 이동할 수 있으려면 다음 공식 통합을 사용할 수 있습니다.
React Navigation의 제한으로 인해 React Navigation 4 통합으로 일부 기능을 사용할 수 없습니다. 예를 들어, 렌더링 된 탭을 동적으로 변경할 수 있습니다.
renderScene 함수는 인덱스가 변경 될 때마다 호출됩니다. renderScene 함수가 비싸면, 인덱스에 의존하지 않으면 각 경로를 별도의 구성 요소로 이동시키고 경로 구성 요소에서 shouldComponentUpdate 또는 React.memo 사용하여 불필요한 재 렌즈를 방지합니다.
예를 들어 : 대신 :
const renderScene = ( { route } ) => {
switch ( route . key ) {
case 'home' :
return (
< View style = { styles . page } >
< Avatar />
< NewsFeed />
</ View >
) ;
default :
return null ;
}
} ;다음을 수행하십시오.
const renderScene = ( { route } ) => {
switch ( route . key ) {
case 'home' :
return < HomeComponent /> ;
default :
return null ;
}
} ; 여기서 <HomeComponent /> 클래스 구성 요소를 사용하는 경우 PureComponent 입니다.
export default class HomeComponent extends React . PureComponent {
render ( ) {
return (
< View style = { styles . page } >
< Avatar />
< NewsFeed />
</ View >
) ;
}
} 또는 기능 구성 요소를 사용하는 경우 React.memo 로 싸서 :
function HomeComponent ( ) {
return (
< View style = { styles . page } >
< Avatar />
< NewsFeed />
</ View >
) ;
}
export default React . memo ( HomeComponent ) ;컨테이너의 너비를 측정해야하므로 화면의 일부 요소를 렌더링하기 전에 기다려야합니다. 초기 너비를 선불로 알고 있다면 전달할 수 있으며 측정을 기다릴 필요가 없습니다. 대부분의 경우 창 너비 일뿐입니다.
예를 들어, 다음 initialLayout TabView 로 전달하십시오.
const initialLayout = {
height : 0 ,
width : Dimensions . get ( 'window' ) . width ,
} ;탭보기는 여전히 차원의 변화에 반응하고 방향 변경과 같은 것들을 수용하도록 조정합니다.
많은 수의 경로, 특히 이미지가 있다면 애니메이션을 많이 느리게 할 수 있습니다. 대신 제한된 수의 경로를 렌더링 할 수 있습니다.
예를 들어, 각 측면에서 2 개의 경로 만 렌더링하려면 다음을 수행하십시오.
const renderScene = ( { route } ) => {
if ( Math . abs ( index - routes . indexOf ( route ) ) > 2 ) {
return < View /> ;
}
return < MySceneComponent route = { route } /> ;
} ; 수직 ScrollView 내부에서 TabView 중첩하면 TabView 내부에 렌더링 된 FlatList 구성 요소의 최적화가 비활성화됩니다. 따라서 가능하면 그렇게하지 마십시오.
lazy 및 renderLazyPlaceholder 소품을 사용하여 필요에 따라 경로를 렌더링하십시오. lazy 옵션은 기본적으로 부드러운 탭 전환 경험을 제공하기 위해 기본적으로 비활성화되지만이를 활성화하고 더 나은 게으른로드 경험을위한 자리 표시 자 구성 요소를 제공 할 수 있습니다. lazy 활성화하면 경로가 볼 때만 경로를 렌더링하여 초기 부하 성능을 향상시킬 수 있습니다. 자세한 내용은 소품 참조를 참조하십시오.
개발하는 동안 예제 앱을 실행하여 변경 사항을 테스트 할 수 있습니다.
코드가 TypeScript와 Eslint를 통과해야합니다. 확인하려면 다음을 실행하십시오.
yarn typescript
yarn lint서식 오류를 수정하려면 다음을 실행하십시오.
yarn lint -- --fix가능한 경우 변경 테스트를 추가해야합니다.