React Native NavigationExperimental
OverviewNavigationExperimental是react native的一个新的导航系统,重点是改进<Navigator/>组件.
如果你对react native 中的三个导航感到困惑,可以查看导航比较的文章 三个导航系统的比较Navigator 和 NavigatorIOS 对于新人来说,不知道如何区别它们。一个是基于JS的,而NavigatorIOS则是第三方的开发的只针对ios的本地组件. 而Facebook正在将Navigator 过渡到NavigationExperimental. NavigationExperimental向前兼容navigation库。 NavigationExperimental 通常称为”新的导航”,但其实它是以一种新的方法实现导航逻辑,这样允许作何的视图都可以作为导航的视图 。它包含了一个预编异的组件NavigationAnimatedView来管理场景间的动画。它内部的每一个视图都可以有自己的手势和动画。这些预编译的场景和overlay组件,看起来就会跟平台相一致(ios,android) Navigator and NavigatorIOS两个都是有状态(即保存各个导航的序顺)的组件,允许你的APP在多个不同的场景(屏幕)之间管理你的导航。这两个导航管理了一个路由栈(route stack),这样就允许我们使用pop(),psh(),and replace()来管理状态。这类似于html5的history API. 这两者的主要区别在于NavigatorIOS是使用了iOS的 UINavigationController类,而Navigator都是基于Javascript。 Navigator适用于两个平台,而NavigatorIOS只能适用于iOS. 如果在一个APP中应用了多个导航组件(Navigator and NavigatorIOS一起使用). 那么在两者之间进行导航过渡,会变得非常困难. NavigationExperimental
Navigator
NavigatorIOS
NavigationExperimental 文档Navigation State你整个app的导航状态(state)可以被NavigationStates模式化,一个NavigationState是一个对像。 const myState = {
key: 'myPage0',myType: 'ExamplePage',myParams: {foo:'bar'},}
一个NavigationParentState 包含一组路由(routes),并且有一个index字段,表示当前的路由 const myState = {
key: 'myAppTabs',routes: [
{key: 'home'},{key: 'notifs'},{key: 'settings'},],index: 1,// points to the 'notifs' tab
}
navigation state types在NavigationStateUtils中保存,同时在NavigationStateUtils还有一些函数,通过这些函数可以改变NavigationParentState。 Containers在NavigationExperimental中提供了一个最顶级的组件,用于维护导航的状态以及处理永久性(将导航保存到硬盘或者从硬盘中读取导航的状态数据)。 NavigationRootContainer开发者可以为根容器设置一个reducer,reducer会包含整个app的导航逻辑。我们的navigation reducers将会接受最后的导航状态,一个我们需要处理的action. 然后它为我们的app输出一个新的导航装态。为了获得初始化的state,reducers可以在调用时,不需要上一个状态或者action. <NavigationRootContainer reducer={MyReducer} renderNavigation={(navigationState, onNavigate) => (
<Text>Currently at {navigationState.routes[navigationState.index]}</Text>
它也提供了一个针对navigation action的处理器,并且允许reducer被自定义. NavigationContainer.create在整个应用中,都要传递onNavigate会非常繁锁,因此我们可以提供一个更高阶的”container”组件。 <NavigationRootContainer
reducer={MyReducer}
renderNavigation={(navigationState) => <ExampleComponent />}
...
class ExampleComponent {
render() {
<Text onPress={() => { this.props.onNavigate(new ExampleAction()) }}>
This action will work,even though `onNavigate` was not directly passed in
</Text>
}
}
ExampleComponent = NavigationContainer.create(ExampleComponent);
如果onNavigation作为一个属性被传递给container,它会覆盖处理程序中包含的组件和所有的子容器. Reducers一个导航的reducer是一个action 处理器,它返回当前的navigation state.当调用navigation reducers,你要提供一个可选的previous state和一个字符串类型的 navigation action. let state = MyReducer(null,{ type: 'InitialAction' });
//output
> {
key: 'Root',index: 0,routes: [
{key: 'Home'},]
}
state = MyReducer(state,{ type: 'PushPerson',name: 'Christopher' });
//output
> {
key: 'Root',index: 1,{key: 'Person0',name: 'Christopher'},]
}
Stack Reducer常见的导航逻辑是一个’stack’(栈),这可以通过stack reducer来处理 const MyReducer = NavigationStackReducer({
// First,define the initial parent state that will be used if there was no previous state.
initialState: {
key: 'Root',]
},getPushedReducerForAction: (action) => {
if (action.type === 'PushPerson') {
// We need to push some additional state,that will be defined by this reducer:
return () => ({
key: 'Person'+(i++),name: action.name,});
}
// In this case we do not need to push,so our reducer for this action is nothing
return null;
},});
let state = MyReducer(null,{ type: 'InitAction' });
> {
key: 'Root',]
}
state = MyReducer(state,name: 'Christopher' });
> {
key: 'Root',]
}
// The back action can be used to pop:
state = MyReducer(state,NavigationRootContainer.getBackAction());
> {
key: 'Root',]
}
stack reducer中也可以包含sub-reducers,它需要你实现getReducerForState. 它会为sub-state 返回一个sub-reducer. 当前的sub-state的sub-reducer将会被使用. Tabs ReducerTabs reducer允许你有多个子sub-reducers,但有一个是激活状态。对于每一个action,都会被发送给tabs reducer,它会首先使用active状态的sub-reducer. 如果reducers没有返回一个新的sub-state,则另外的reducers将会获得机会,并进行处理。如果一个不同的tab reducer处理了它,tabs reducer将返回一个新的new sub-state,并且交换active tab. Find ReducerReducers的一个常见模式是组合了多个reducers,当其中一个reducer返回一个新的state时停止。Find Reducer会接受一个reducers数组,然后遍历数据中的每一个元素,直到state改变时,返回这个reducer. 如果这些reducers没有返回一个新的state,find reducer将返回默认的state. ViewsNavigationView最简单的视图是render当前sub-state的场景(scene). 常用于tabs,因为它不需要转换。 NavigationAnimateViewNavigationAnimateView 采用声明API,它使用Animate library向scenes委派动画和手势 NavigationCard和NavigationHeader就是场景和叠加的NavigationAnimateView。这是为了看起来跟iOS或android一样。 NavigationCard<NavigationAnimatedView navigationState={navigationState} renderScene={(props) => (
<NavigationCard key={props.navigationState.key} index={props.index} navigationState={props.navigationParentState} position={props.position} layout={props.layout}>
<MyInnerView info={props.navigationState} />
</NavigationCard>
)}
/>
NavigationHeader<NavigationAnimatedView navigationState={navigationState} renderOverlay={(props) => (
<NavigationHeader navigationState={props.navigationParentState} position={props.position} getTitle={state => state.key}
/>
)}
renderScene={this._renderScene}
/>
NavigationCardStack包装了NavigationAnimateView,可以为每一个Scene,render一个NavigationCard. 类似于过时的Navigator. 这是因为它内置了animations和gestures 使用: render() { return ( <NavigationCardStack style={styles.main} renderScene={props => <MyPetView name={props.navigationState.key} species={props.navigationState.species} /> } renderOverlay={props => <NavigationHeader {...props} />} navigationState={{ key: 'MyPetStack',index: 2,routes: [ {key: 'Pluto',species: 'dog'},{key: 'Snoopy',{key: 'Garfield',species: 'cat'},] }} /> ); }
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |